Template
1
0
mirror of https://github.com/bol-van/zapret2.git synced 2026-03-19 15:55:48 +00:00

93 Commits

Author SHA1 Message Date
bol-van
c6c01c63c3 update docs 2026-03-16 12:17:48 +03:00
bol-van
7d1baf6123 zapret-pcap: fix keep argument 2026-03-14 15:17:34 +03:00
bol-van
7cdc75d0db github: remove sdiv crash on old armv7 2026-03-12 20:51:57 +03:00
bol-van
348f907b47 winws2: remove .buildid section 2026-03-12 17:40:11 +03:00
bol-van
d641b00083 winws2: update res bins 2026-03-12 17:31:02 +03:00
bol-van
d3b3011000 AI fixes 2026-03-06 21:36:09 +03:00
bol-van
2ec512af17 AI fixes 2026-03-06 10:58:05 +03:00
bol-van
d41151ef6f nfqws2: join fragments in quic CRYPTO reconstruction. allow intersections 2026-03-05 18:38:44 +03:00
bol-van
60ac3693fc nfqws2: optimize quic CRYPTO defrag 2026-03-05 09:41:41 +03:00
bol-van
766b60544f nfqws2: remove unused var 2026-03-04 22:50:31 +03:00
bol-van
e563f60153 AI fixes 2026-03-04 22:36:31 +03:00
bol-van
6d7f8efc49 nfqws2: optimize quic CRYPTO defrag 2026-03-04 19:33:49 +03:00
bol-van
e46cde8e6e nfqws2: optimize 2026-03-04 18:58:39 +03:00
bol-van
52072359f0 nfqws2: remove unneeded function 2026-03-04 18:54:38 +03:00
bol-van
cafacf35bc nfqws2: quic CRYPTO frag early dedup 2026-03-04 18:52:47 +03:00
bol-van
55dc47bae4 nfqws2: remove unneeded loop 2026-03-04 14:16:19 +03:00
bol-van
14a2548bf5 nfqws2: allow quic CRYPTO fragment intersection and dups 2026-03-04 12:31:40 +03:00
bol-van
f59ddbb645 github,linux-builder: revert to lj_alloc for arm64 and mips64 2026-03-03 19:25:33 +03:00
bol-van
96f58adc7a docs 2026-03-03 10:53:05 +03:00
bol-van
b20ee9adbe zapret-lib: prevent double apply_arg_prefix 2026-03-03 10:49:55 +03:00
bol-van
7bfb4066cd update docs 2026-03-02 20:24:45 +03:00
bol-van
a8a742f48c zapret-lib: call apply_arg_prefix right before instance execute 2026-03-02 20:21:38 +03:00
bol-van
03f1fc4788 init.d: warn if ipset/hostlist files inside zapret2 root 2026-03-02 14:18:57 +03:00
bol-van
3ae875f8aa AI fixes 2026-03-02 10:44:48 +03:00
bol-van
300084a654 github.linux-builder: move arm to armv6 2026-03-01 20:22:02 +03:00
bol-van
ccef4377df github: use thumb in android armv7 build 2026-03-01 18:30:54 +03:00
bol-van
3ebb24930e -DLUAJIT_USE_SYSMALLOC 2026-03-01 10:22:19 +03:00
bol-van
aff6fe3966 -DLUAJIT_USE_SYSMALLOC 2026-03-01 10:18:35 +03:00
bol-van
f43030c0b8 AI fix 2026-03-01 09:53:55 +03:00
bol-van
69e8bb3c7f AI fixes 2026-03-01 09:48:18 +03:00
bol-van
038f64ddad update docs 2026-02-28 22:30:08 +03:00
bol-van
abdf88574c github: build experiment 2026-02-28 22:25:47 +03:00
bol-van
318c625247 update builder-linux 2026-02-28 22:23:13 +03:00
bol-van
3e52d53df0 update builder-linux 2026-02-28 19:14:45 +03:00
bol-van
410ba5ae6e github: build experiment 2026-02-28 19:02:11 +03:00
bol-van
bee761f0f7 github: build experiment 2026-02-28 18:53:51 +03:00
bol-van
863267e659 github: build experiment 2026-02-28 18:47:25 +03:00
bol-van
c0299a27e3 github: build experiment 2026-02-28 18:43:24 +03:00
bol-van
b9e22fd97e github: luajit host CFLAGS -O2 2026-02-28 18:41:18 +03:00
bol-van
b3a6445d13 update builder-linux 2026-02-28 18:40:51 +03:00
bol-van
75e3c83d07 github: armv7 thumb 2026-02-28 18:33:56 +03:00
bol-van
1aaf73858c builder-linux armv7 thumb 2026-02-28 18:29:28 +03:00
bol-van
827b1cf065 AI fixes 2026-02-28 10:10:26 +03:00
bol-van
e0f67fb203 AI fixes 2026-02-27 14:34:35 +03:00
bol-van
da6f4c8536 init.d: remove KillMode=none from systemd unit 2026-02-26 22:05:29 +03:00
bol-van
f83ecb64bb pie experiment 2026-02-26 21:23:53 +03:00
bol-van
c634fd156c update builder-linux 2026-02-26 20:03:50 +03:00
bol-van
c10cc5b83e update builder-linux 2026-02-26 18:46:19 +03:00
bol-van
60988755b7 update builder-linux 2026-02-26 18:41:36 +03:00
bol-van
7584d5e38f update makefiles 2026-02-26 16:44:58 +03:00
bol-van
d019627fba nfqws2: e2k arch seccomp support 2026-02-26 16:34:47 +03:00
bol-van
1ac067ec32 nfqws2: separate strip option 2026-02-26 15:09:29 +03:00
bol-van
1b5811aa9a nfqws2: silence warning 2026-02-26 11:01:13 +03:00
bol-van
60c3f56c36 pie experiment 2026-02-26 10:53:35 +03:00
bol-van
a0cfbbf958 pie experiment 2026-02-26 10:46:59 +03:00
bol-van
437c988f48 pie experiment 2026-02-26 10:43:45 +03:00
bol-van
a9a64b0462 pie experiment 2026-02-26 10:37:15 +03:00
bol-van
9887e470dc update builder-linux 2026-02-26 10:35:31 +03:00
bol-van
5bacfcb65f pie experiment 2026-02-26 10:28:58 +03:00
bol-van
0f04698f07 pie experiment 2026-02-26 10:21:23 +03:00
bol-van
31d5e5598b pie experiment 2026-02-26 10:19:24 +03:00
bol-van
66e2cc2bc4 pie experiment 2026-02-26 10:10:28 +03:00
bol-van
8fcc64ad0c pie experiment 2026-02-26 09:47:25 +03:00
bol-van
d2f3271542 dvtws2: build with PIE 2026-02-25 17:34:36 +03:00
bol-van
942c4956b8 github: rebase windivert.dll to >4gb to allow hi entropy aslr 2026-02-25 14:33:38 +03:00
bol-van
77a24a7ec1 github: set dynamicbase on windivert.dll 2026-02-25 12:22:28 +03:00
bol-van
43999d6077 winws2: enable ASLR 2026-02-25 10:49:07 +03:00
bol-van
697f9fc986 AI fixes 2026-02-25 08:56:35 +03:00
bol-van
8e76197dff luacheck fixes 2026-02-24 19:07:04 +03:00
bol-van
190f46b6d7 zapret-lib: minor fix 2026-02-24 18:43:49 +03:00
bol-van
41e26b3ace update docs 2026-02-24 16:32:21 +03:00
bol-van
8b6ea88a23 update docs 2026-02-24 10:19:01 +03:00
bol-van
59235827c4 nfqws2: fix broken wifi ssid update 2026-02-24 10:10:52 +03:00
bol-van
7073e1fd77 nfqws2: dns_extract_name OOB fixes 2026-02-23 22:47:14 +03:00
bol-van
340261da72 zapret-lib: harden apply_fooling checks 2026-02-23 19:33:58 +03:00
bol-van
937aa91e5d nfqws2: prevent OOB read in addpool 2026-02-23 18:45:25 +03:00
bol-van
dbf673e24a AI fixes 2026-02-23 18:10:37 +03:00
bol-van
61b0a70fa7 nfqws2: support mixed compressed+uncomressed DNS answers 2026-02-23 10:25:27 +03:00
bol-van
d985bb316f nfqws2: support uncompressed names in DNS answers 2026-02-23 09:32:45 +03:00
bol-van
59b3734643 nfqws2: add comment 2026-02-22 19:41:08 +03:00
bol-van
37f45a132f nfqws2: optimize 2026-02-22 18:49:44 +03:00
bol-van
4d753ecdc6 nfqws2: save some syscalls 2026-02-22 18:22:43 +03:00
bol-van
272f086639 nfqws2: optimize nfq buffers 2026-02-22 17:31:13 +03:00
bol-van
d9ae16e56f nfqws2: nfq_handle_packet verbose error logging 2026-02-22 17:03:52 +03:00
bol-van
46d4208c76 zapret-pcap: use reconstruct_dissect if under orchestrator 2026-02-22 12:48:20 +03:00
bol-van
2a4195070f AI fixes 2026-02-22 09:06:53 +03:00
bol-van
8e974e78e2 delete sip.bin dup 2026-02-21 19:44:00 +03:00
bol-van
7df42bc486 init.d: --payload= in custom examples 2026-02-21 10:35:14 +03:00
bol-van
7c12f60e1e AI fixes 2026-02-21 10:23:25 +03:00
bol-van
4c7a3d08d8 github: upx 4.2.4 for all except riscv64 2026-02-20 18:43:22 +03:00
bol-van
e146fc24c5 github: upx 4.2.4 for all except riscv64 2026-02-20 18:41:18 +03:00
bol-van
6165c13468 AI fix 2026-02-20 15:25:56 +03:00
bol-van
f7b3946ec2 update docs 2026-02-20 13:19:17 +03:00
53 changed files with 605 additions and 312 deletions

View File

@@ -25,7 +25,7 @@ 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: mips64 - arch: mips64
tool: mips64-unknown-linux-musl tool: mips64-unknown-linux-musl
- arch: mipselsf - arch: mipselsf
@@ -88,6 +88,8 @@ jobs:
LUAJIT_LUAVER: 5.1 LUAJIT_LUAVER: 5.1
MINSIZE: -flto=auto -ffunction-sections -fdata-sections MINSIZE: -flto=auto -ffunction-sections -fdata-sections
LDMINSIZE: -Wl,--gc-sections -flto=auto LDMINSIZE: -Wl,--gc-sections -flto=auto
#current toolchain's musl is not PIC. will be broken by upx
#PIC: -fpic
run: | run: |
DEPS_DIR=$GITHUB_WORKSPACE/deps DEPS_DIR=$GITHUB_WORKSPACE/deps
export CC="$TARGET-gcc" export CC="$TARGET-gcc"
@@ -97,11 +99,20 @@ 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
if [ "$ARCH" = lexra ]; then OPTIMIZE=-Oz
OPTIMIZE=-Os SYSMALLOC=-DLUAJIT_USE_SYSMALLOC
else case "$ARCH" in
OPTIMIZE=-Oz lexra)
fi OPTIMIZE=-Os
;;
arm)
CPU="-mcpu=arm1176jzf-s -mthumb"
;;
arm64|mips64)
# not safe without GC64
SYSMALLOC=
;;
esac
MINSIZE="$OPTIMIZE $MINSIZE" MINSIZE="$OPTIMIZE $MINSIZE"
if [[ "$ARCH" == lexra ]] || [[ "$ARCH" == riscv64 ]] || [[ "$ARCH" == x86 ]] ; then if [[ "$ARCH" == lexra ]] || [[ "$ARCH" == riscv64 ]] || [[ "$ARCH" == x86 ]] ; then
@@ -109,7 +120,7 @@ jobs:
wget -qO- https://www.lua.org/ftp/lua-${LUA_RELEASE}.tar.gz | tar -xz wget -qO- https://www.lua.org/ftp/lua-${LUA_RELEASE}.tar.gz | tar -xz
( (
cd lua-${LUA_RELEASE} cd lua-${LUA_RELEASE}
make CC=$CC AR="$AR rc" CFLAGS="$MINSIZE $CFLAGS" LDFLAGS="$LDMINSIZE $LDFLAGS" linux -j$(nproc) make CC=$CC AR="$AR rc" CFLAGS="$CPU $MINSIZE $CFLAGS" LDFLAGS="$LDMINSIZE $LDFLAGS" linux -j$(nproc)
make install INSTALL_TOP=$DEPS_DIR INSTALL_BIN=$DEPS_DIR/bin INSTALL_INC=$DEPS_DIR/include/lua${LUA_VER} INSTALL_LIB=$DEPS_DIR/lib make install INSTALL_TOP=$DEPS_DIR INSTALL_BIN=$DEPS_DIR/bin INSTALL_INC=$DEPS_DIR/include/lua${LUA_VER} INSTALL_LIB=$DEPS_DIR/lib
) )
LJIT=0 LJIT=0
@@ -125,9 +136,10 @@ jobs:
*) *)
HOSTCC="cc -m32" HOSTCC="cc -m32"
esac esac
echo ARCH=$ARCH SYSMALLOC=$SYSMALLOC
( (
cd luajit2-* cd luajit2-*
make BUILDMODE=static XCFLAGS=-DLUAJIT_DISABLE_FFI HOST_CC="$HOSTCC" CROSS= CC="$CC" TARGET_AR="$AR rcus" TARGET_STRIP=$STRIP TARGET_CFLAGS="$MINSIZE $CFLAGS" TARGET_LDFLAGS="$LDMINSIZE $LDFLAGS" -j$(nproc) make BUILDMODE=static XCFLAGS="$SYSMALLOC -DLUAJIT_DISABLE_FFI" HOST_CC="$HOSTCC" CROSS= CC="$CC" TARGET_AR="$AR rcus" TARGET_STRIP=$STRIP TARGET_CFLAGS="$CPU $MINSIZE $CFLAGS" TARGET_LDFLAGS="$CPU $LDMINSIZE $LDFLAGS" -j$(nproc)
make install PREFIX= DESTDIR=$DEPS_DIR make install PREFIX= DESTDIR=$DEPS_DIR
) )
LJIT=1 LJIT=1
@@ -143,7 +155,7 @@ jobs:
for i in libmnl libnfnetlink libnetfilter_queue ; do for i in libmnl libnfnetlink libnetfilter_queue ; do
( (
cd $i-* cd $i-*
CFLAGS="$MINSIZE $CFLAGS" \ CFLAGS="$CPU $MINSIZE $CFLAGS" \
LDFLAGS="$LDMINSIZE $LDFLAGS" \ LDFLAGS="$LDMINSIZE $LDFLAGS" \
./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
@@ -156,7 +168,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="$MINSIZE $CFLAGS" \ CFLAGS="$CPU $MINSIZE $CFLAGS" \
./configure --prefix= --static ./configure --prefix= --static
make install -j$(nproc) DESTDIR=$DEPS_DIR make install -j$(nproc) DESTDIR=$DEPS_DIR
) )
@@ -168,9 +180,9 @@ jobs:
# zapret2 # zapret2
OPTIMIZE=$OPTIMIZE \ OPTIMIZE=$OPTIMIZE \
CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }} -static-libgcc -static -I$DEPS_DIR/include $CFLAGS" \ CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }} -static-libgcc -I$DEPS_DIR/include $CPU $CFLAGS" \
LDFLAGS="-L$DEPS_DIR/lib $LDFLAGS" \ LDFLAGS="-L$DEPS_DIR/lib $LDFLAGS" \
make -C zapret2 LUA_JIT=$LJIT LUA_CFLAGS="$LCFLAGS" LUA_LIB="$LLIB" -j$(nproc) make -C zapret2 CFLAGS_PIC= LDFLAGS_PIE=-static LUA_JIT=$LJIT LUA_CFLAGS="$LCFLAGS" LUA_LIB="$LLIB" -j$(nproc)
tar -C zapret2/binaries/my -cJf zapret2-linux-$ARCH.tar.xz . tar -C zapret2/binaries/my -cJf zapret2-linux-$ARCH.tar.xz .
@@ -230,6 +242,17 @@ 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
SYSMALLOC=-DLUAJIT_USE_SYSMALLOC
case "$ABI" in
armeabi-v7a)
CPU="-mthumb"
;;
arm64-v8a)
# not safe without GC64
SYSMALLOC=
PAGESIZE="-Wl,-z,max-page-size=16384"
;;
esac
# luajit # luajit
wget -qO- https://github.com/openresty/luajit2/archive/refs/tags/v${LUAJIT_RELEASE}.tar.gz | tar -xz wget -qO- https://github.com/openresty/luajit2/archive/refs/tags/v${LUAJIT_RELEASE}.tar.gz | tar -xz
@@ -242,7 +265,7 @@ jobs:
esac esac
( (
cd luajit2-* cd luajit2-*
make BUILDMODE=static XCFLAGS=-DLUAJIT_DISABLE_FFI HOST_CC="$HOSTCC" CROSS= CC="$CC" TARGET_AR="$AR rcus" TARGET_STRIP=$STRIP TARGET_CFLAGS="$MINSIZE $CFLAGS" TARGET_LDFLAGS="$LDMINSIZE $LDFLAGS" -j$(nproc) make BUILDMODE=static XCFLAGS="$SYSMALLOC -DLUAJIT_DISABLE_FFI" HOST_CC="$HOSTCC" CROSS= CC="$CC" TARGET_AR="$AR rcus" TARGET_STRIP=$STRIP TARGET_CFLAGS="$CPU $MINSIZE $CFLAGS" TARGET_LDFLAGS="$LDMINSIZE $LDFLAGS" -j$(nproc)
make install PREFIX= DESTDIR=$DEPS_DIR make install PREFIX= DESTDIR=$DEPS_DIR
) )
LJIT=1 LJIT=1
@@ -258,7 +281,7 @@ jobs:
for i in libmnl libnfnetlink libnetfilter_queue ; do for i in libmnl libnfnetlink libnetfilter_queue ; do
( (
cd $i-* cd $i-*
CFLAGS="$MINSIZE -Wno-implicit-function-declaration $CFLAGS" \ CFLAGS="$CPU $MINSIZE -Wno-implicit-function-declaration $CFLAGS" \
LDFLAGS="$LDMINSIZE $LDFLAGS" \ LDFLAGS="$LDMINSIZE $LDFLAGS" \
./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
@@ -267,8 +290,8 @@ jobs:
done done
# zapret2 # zapret2
CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }} -I$DEPS_DIR/include" \ CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }} -I$DEPS_DIR/include $CPU" \
LDFLAGS="-L$DEPS_DIR/lib" \ LDFLAGS="-L$DEPS_DIR/lib $PAGESIZE" \
make -C zapret2 LUA_JIT=$LJIT LUA_CFLAGS="$LCFLAGS" LUA_LIB="$LLIB" -j$(nproc) android make -C zapret2 LUA_JIT=$LJIT LUA_CFLAGS="$LCFLAGS" LUA_LIB="$LLIB" -j$(nproc) android
# strip unwanted ELF sections to prevent warnings on old Android versions # strip unwanted ELF sections to prevent warnings on old Android versions
@@ -314,15 +337,16 @@ jobs:
env: env:
TARGET: ${{ matrix.target }} TARGET: ${{ matrix.target }}
ARCH: ${{ matrix.arch }} ARCH: ${{ matrix.arch }}
PIC: -fpic
CC: ${{ matrix.target }}-freebsd11-clang CC: ${{ matrix.target }}-freebsd11-clang
MINSIZE: -Oz -flto=auto -ffunction-sections -fdata-sections MINSIZE: -Os -flto=auto -ffunction-sections -fdata-sections
LDMINSIZE: -Wl,--gc-sections -flto=auto LDMINSIZE: -Wl,--gc-sections -flto=auto
run: | run: |
wget -qO- https://github.com/openresty/luajit2/archive/refs/tags/v${LUAJIT_RELEASE}.tar.gz | tar -xz wget -qO- https://github.com/openresty/luajit2/archive/refs/tags/v${LUAJIT_RELEASE}.tar.gz | tar -xz
( (
cd luajit2-* cd luajit2-*
make BUILDMODE=static XCFLAGS=-DLUAJIT_DISABLE_FFI HOST_CC=gcc CC=$CC TARGET_CFLAGS="$MINSIZE $CFLAGS" TARGET_LDFLAGS="$LDMINSIZE $LDFLAGS" make BUILDMODE=static XCFLAGS="$PIC -DLUAJIT_USE_SYSMALLOC -DLUAJIT_DISABLE_FFI" HOST_CC=gcc CC=$CC TARGET_CFLAGS="$MINSIZE $CFLAGS $PIC" TARGET_LDFLAGS="$LDMINSIZE $LDFLAGS"
make install PREFIX= DESTDIR=$DEPS_DIR make install PREFIX= DESTDIR=$DEPS_DIR
) )
@@ -435,7 +459,7 @@ jobs:
wget -q https://github.com/openresty/luajit2/archive/refs/tags/v${LUAJIT_RELEASE}.tar.gz && wget -q https://github.com/openresty/luajit2/archive/refs/tags/v${LUAJIT_RELEASE}.tar.gz &&
tar -xzf v${LUAJIT_RELEASE}.tar.gz && tar -xzf v${LUAJIT_RELEASE}.tar.gz &&
rm -f v${LUAJIT_RELEASE}.tar.gz && rm -f v${LUAJIT_RELEASE}.tar.gz &&
make -C luajit2-${LUAJIT_RELEASE} BUILDMODE=static XCFLAGS="-DLUAJIT_DISABLE_FFI -ffat-lto-objects" TARGET_CFLAGS="$MINSIZE $CFLAGS" TARGET_LDFLAGS="$LDMINSIZE $LDFLAGS" && make -C luajit2-${LUAJIT_RELEASE} BUILDMODE=static XCFLAGS="-DLUAJIT_USE_SYSMALLOC -DLUAJIT_DISABLE_FFI -ffat-lto-objects" TARGET_CFLAGS="$MINSIZE $CFLAGS" TARGET_LDFLAGS="$LDMINSIZE $LDFLAGS" &&
make -C luajit2-${LUAJIT_RELEASE} install make -C luajit2-${LUAJIT_RELEASE} install
- name: Build winws - name: Build winws
@@ -458,6 +482,8 @@ jobs:
cp -a -t output psmisc/psmisc-*.src/psmisc-*/inst/usr/bin/killall.exe /usr/bin/cygwin1.dll && cp -a -t output psmisc/psmisc-*.src/psmisc-*/inst/usr/bin/killall.exe /usr/bin/cygwin1.dll &&
wget -O WinDivert.zip https://github.com/basil00/WinDivert/releases/download/v2.2.2/WinDivert-2.2.2-A.zip && wget -O WinDivert.zip https://github.com/basil00/WinDivert/releases/download/v2.2.2/WinDivert-2.2.2-A.zip &&
unzip -j WinDivert.zip "*/${DIR}/WinDivert.dll" "*/${DIR}/WinDivert${BITS}.sys" -d output && unzip -j WinDivert.zip "*/${DIR}/WinDivert.dll" "*/${DIR}/WinDivert${BITS}.sys" -d output &&
( [ "$BITS" = 64 ] && rebase -b 0x205c00000 output/WinDivert.dll || true ) &&
peflags --dynamicbase=true --high-entropy-va=true output/WinDivert.dll &&
zip zapret2-win-${{ matrix.arch }}.zip -j output/* zip zapret2-win-${{ matrix.arch }}.zip -j output/*
- name: Upload artifacts - name: Upload artifacts
@@ -490,17 +516,28 @@ jobs:
pattern: zapret2-* pattern: zapret2-*
- name: Install upx - name: Install upx
uses: crazy-max/ghaction-upx@v3 shell: bash
with: env:
install-only: true VER_OLD: 4.2.4
version: v5.1.0 VER_NEW: 5.1.0
run: |
# old upx works for old kernels like 2.6.26
# new upx crashes on ~<3.10 but required for riscv64
curl -Lo - https://github.com/upx/upx/releases/download/v$VER_OLD/upx-$VER_OLD-amd64_linux.tar.xz | tar -Jx upx-$VER_OLD-amd64_linux/upx
sudo cp upx-$VER_OLD-amd64_linux/upx /usr/local/bin/upx_old
curl -Lo - https://github.com/upx/upx/releases/download/v$VER_NEW/upx-$VER_NEW-amd64_linux.tar.xz | tar -Jx upx-$VER_NEW-amd64_linux/upx
sudo cp upx-$VER_NEW-amd64_linux/upx /usr/local/bin/upx_new
rm -r upx-$VER_OLD-amd64_linux/upx upx-$VER_NEW-amd64_linux/upx
- name: Prepare binaries - name: Prepare binaries
shell: bash shell: bash
run: | run: |
cd ${{ steps.bins.outputs.download-path }} cd ${{ steps.bins.outputs.download-path }}
run_upx() { run_upx_old() {
upx --best --lzma $@ || true upx_old --best --lzma $@ || true
}
run_upx_new() {
upx_new --best --lzma $@ || true
} }
run_dir() { run_dir() {
for f in $dir/* ; do for f in $dir/* ; do
@@ -508,8 +545,10 @@ jobs:
case $f in case $f in
*.tar.xz ) *.tar.xz )
tar -C $dir -xvf $f && rm $f tar -C $dir -xvf $f && rm $f
if [[ $dir =~ linux ]] && [[ $dir != *-linux-mips64 ]] && [[ $dir != *-linux-lexra ]]; then if [[ $dir = *-linux-riscv64 ]]; then
run_upx $dir/* run_upx_new $dir/*
elif [[ $dir =~ linux ]] && [[ $dir != *-linux-mips64 ]] && [[ $dir != *-linux-lexra ]]; then
run_upx_old $dir/*
fi fi
;; ;;
*.zip ) *.zip )

View File

@@ -438,6 +438,13 @@ has_bad_ws_options()
echo "Kernel ipsets should be used instead. Write custom scripts and filter IPs in kernel." echo "Kernel ipsets should be used instead. Write custom scripts and filter IPs in kernel."
echo echo
} }
contains "$1" "--ipset=$ZAPRET_BASE" || contains "$1" "--ipset-exclude=$ZAPRET_BASE" ||
contains "$1" "--hostlist=$ZAPRET_BASE" || contains "$1" "--hostlist-exclude=$ZAPRET_BASE" && {
echo
echo "WARNING !!! you store ipset or hostlist files inside '$ZAPRET_BASE'"
echo "It's not recommended. install_easy.sh will delete them during update."
echo
}
return 1 return 1
} }

View File

@@ -252,4 +252,24 @@ v0.9.4
v0.9.4.2 v0.9.4.2
* builder_linux: simple scripts to build static linux bins for any supported architecture * builder_linux: simple scripts to build static linux bins for any supported architecture
* zapret-auto: incompatible change. cond_code "code" parameter => "cond_code". to avoid collision with luaexec * zapret-auto: incompatible change. cond_lua "code" parameter => "cond_code". to avoid collision with luaexec
v0.9.4.3
* nfqws2: fix broken wifi ssid update
* github: revert to upx 4.2.4 for all archs except riscv64
* zapret-lib: apply_fooling throws error if tcp_ts,tcp_seq,tcp_ack,ip_ttl,ip6_ttl,ip_autottl,ip6_autottl are empty or invalid
0.9.4.4
* winws2, dvtws2: ASLR
* github, linux-builder: reduce arm executable size by 20% - move to armv7+thumb
* init.d: warn if hostlist/ipset files are inside zapret2 root
* zapret-lib: do not call apply_arg_prefix in apply_execution_plan - call it right before instance execute
0.9.4.5
* github: rollback to lj_alloc in luajit for arm64 and mips64
* github: use 16K page size for android arm64 build
* nfqws2: join fragments in quic CRYPTO reconstruction. allow intersections.

View File

@@ -3,6 +3,11 @@
apt install make gcc zlib1g-dev libcap-dev libnetfilter-queue-dev libmnl-dev libsystemd-dev libluajit2-5.1-dev apt install make gcc zlib1g-dev libcap-dev libnetfilter-queue-dev libmnl-dev libsystemd-dev libluajit2-5.1-dev
make -C /opt/zapret2 systemd make -C /opt/zapret2 systemd
* fedora, rhel, centos, alma
dnf add make gcc zlib-devel libcap-devel libnetfilter_queue-devel libmnl-devel systemd-devel luajit-devel
make -C /opt/zapret2 systemd
* linux static : * linux static :
need any x86_64 classic linux distribution need any x86_64 classic linux distribution

View File

@@ -61,10 +61,21 @@ build_lua()
} }
build_luajit() build_luajit()
{ {
local CFL="$CFLAGS"
local SYSMALLOC=
( (
cd luajit2-* cd luajit2-*
CFLAGS="-Os"
make clean make clean
make BUILDMODE=static XCFLAGS=-DLUAJIT_DISABLE_FFI HOST_CC="$HOST_CC" CROSS= CC="$CC" TARGET_AR="$AR rcus" TARGET_STRIP=$STRIP TARGET_CFLAGS="$OPTIMIZE $MINSIZE $CFLAGS" TARGET_LDFLAGS="$LDMINSIZE $LDFLAGS" case $TARGET in
aarch64*|mips64*)
# sysmalloc can cause troubles without GC64. GC64 slows down by 10-15%. better not to use sysmalloc and leave lj_alloc.
;;
*)
# save some exe size
SYSMALLOC=-DLUAJIT_USE_SYSMALLOC
esac
make BUILDMODE=static XCFLAGS="$SYSMALLOC -DLUAJIT_DISABLE_FFI $CFLAGS_PIC" HOST_CC="$HOST_CC" CROSS= CC="$CC" TARGET_AR="$AR rcus" TARGET_STRIP=$STRIP TARGET_CFLAGS="$OPTIMIZE $MINSIZE $CFL" TARGET_LDFLAGS="$CPU $LDMINSIZE $LDFLAGS"
make install PREFIX= DESTDIR="$STAGING_DIR" make install PREFIX= DESTDIR="$STAGING_DIR"
) )
} }
@@ -89,8 +100,11 @@ dl_deps
check_toolchains check_toolchains
ask_target ask_target
CFLAGS_BASE="$CFLAGS"
for t in $TGT; do for t in $TGT; do
CFLAGS="$CFLAGS_BASE"
buildenv $t buildenv $t
CFLAGS="$CFLAGS $CFLAGS_PIC"
pushd "$DEPS" pushd "$DEPS"
install_h_files install_h_files
build_netlink build_netlink

View File

@@ -36,7 +36,9 @@ ask_target
[ -d "$ZBIN" ] || mkdir -p "$ZBIN" [ -d "$ZBIN" ] || mkdir -p "$ZBIN"
CFLAGS_BASE="$CFLAGS"
for t in $TGT; do for t in $TGT; do
CFLAGS="$CFLAGS_BASE $MINSIZE"
buildenv $t buildenv $t
translate_target $t || { translate_target $t || {
@@ -48,8 +50,8 @@ for t in $TGT; do
make clean make clean
OPTIMIZE=$OPTIMIZE \ OPTIMIZE=$OPTIMIZE \
CFLAGS="-static-libgcc -static -I$STAGING_DIR/include $MINSIZE $CFLAGS" \ CFLAGS="-static-libgcc -I$STAGING_DIR/include $CFLAGS $CFLAGS_PIC" \
LDFLAGS="-L$STAGING_DIR/lib $LDMINSIZE $LDFLAGS" \ LDFLAGS="-L$STAGING_DIR/lib $LDMINSIZE $LDFLAGS_PIE $LDFLAGS" \
make make
[ -d "$ZBIN/$ZBINTARGET" ] || mkdir "$ZBIN/$ZBINTARGET" [ -d "$ZBIN/$ZBINTARGET" ] || mkdir "$ZBIN/$ZBINTARGET"

View File

@@ -36,7 +36,9 @@ ask_target
[ -d "$ZBIN" ] || mkdir -p "$ZBIN" [ -d "$ZBIN" ] || mkdir -p "$ZBIN"
CFLAGS_BASE="$CFLAGS"
for t in $TGT; do for t in $TGT; do
CFLAGS="$CFLAGS_BASE"
buildenv $t buildenv $t
translate_target $t || { translate_target $t || {
@@ -59,9 +61,9 @@ for t in $TGT; do
LUA_JIT=$LUA_JIT LUA_VER=$LUA_VER LUAJIT_LUA_VER=$LUAJIT_LUA_VER \ LUA_JIT=$LUA_JIT LUA_VER=$LUA_VER LUAJIT_LUA_VER=$LUAJIT_LUA_VER \
OPTIMIZE=$OPTIMIZE \ OPTIMIZE=$OPTIMIZE \
MINSIZE=$MINSIZE \ MINSIZE=$MINSIZE \
CFLAGS="-static-libgcc -static -I$STAGING_DIR/include $CFLAGS" \ CFLAGS="-static-libgcc -I$STAGING_DIR/include $CFLAGS" \
LDFLAGS="-L$STAGING_DIR/lib $LDFLAGS" \ LDFLAGS="-L$STAGING_DIR/lib $LDFLAGS" \
make LUA_JIT=$LJIT LUA_CFLAGS="$LCFLAGS" LUA_LIB="$LLIB" make CFLAGS_PIC="$CFLAGS_PIC" LDFLAGS_PIE="$LDFLAGS_PIE" LUA_JIT=$LJIT LUA_CFLAGS="$LCFLAGS" LUA_LIB="$LLIB"
[ -d "$ZBIN/$ZBINTARGET" ] || mkdir "$ZBIN/$ZBINTARGET" [ -d "$ZBIN/$ZBINTARGET" ] || mkdir "$ZBIN/$ZBINTARGET"
cp -f binaries/my/* "$ZBIN/$ZBINTARGET" cp -f binaries/my/* "$ZBIN/$ZBINTARGET"

View File

@@ -5,10 +5,14 @@ TOOLCHAINS="$EXEDIR/toolchain"
DEPS="$EXEDIR/deps" DEPS="$EXEDIR/deps"
STAGE="$EXEDIR/staging" STAGE="$EXEDIR/staging"
OPTIMIZE=${OPTIMIZE:--Oz} OPTIMIZE=${OPTIMIZE:--Oz}
MINSIZE="${MINSIZE:--flto=auto -ffunction-sections -fdata-sections}" #MINSIZE="${MINSIZE:--flto=auto -ffunction-sections -fdata-sections}"
MINSIZE="${MINSIZE:--ffunction-sections -fdata-sections}"
LDMINSIZE="${LDMINSIZE:--Wl,--gc-sections -flto=auto}" LDMINSIZE="${LDMINSIZE:--Wl,--gc-sections -flto=auto}"
#CFLAGS="" #CFLAGS=""
LDFLAGS="-lgcc_eh $LDFLAGS" LDFLAGS="-lgcc_eh $LDFLAGS"
# PIE makes ASLR working but adds 5% to size
# PIE does not work for arm32 and all mips
PIE=${PIE:-0}
HOSTCC=${HOSTCC:-cc} HOSTCC=${HOSTCC:-cc}
LUA_VER=${LUA_VER:-5.5} LUA_VER=${LUA_VER:-5.5}
LUA_RELEASE=${LUA_RELEASE:-5.5.0} LUA_RELEASE=${LUA_RELEASE:-5.5.0}
@@ -19,7 +23,7 @@ nproc=$(nproc)
TARGETS="\ TARGETS="\
aarch64-unknown-linux-musl \ aarch64-unknown-linux-musl \
arm-unknown-linux-musleabi \ armv6-unknown-linux-musleabi \
i586-unknown-linux-musl \ i586-unknown-linux-musl \
x86_64-unknown-linux-musl \ x86_64-unknown-linux-musl \
mips-unknown-linux-muslsf \ mips-unknown-linux-muslsf \
@@ -34,7 +38,7 @@ target_has_luajit()
{ {
case "$1" in case "$1" in
aarch64-unknown-linux-musl| \ aarch64-unknown-linux-musl| \
arm-unknown-linux-musleabi| \ armv6-unknown-linux-musleabi| \
x86_64-unknown-linux-musl| \ x86_64-unknown-linux-musl| \
mips-unknown-linux-muslsf| \ mips-unknown-linux-muslsf| \
mips64-unknown-linux-musl| \ mips64-unknown-linux-musl| \
@@ -89,7 +93,27 @@ buildenv()
export PKG_CONFIG_PATH=$STAGING_DIR/lib/pkgconfig export PKG_CONFIG_PATH=$STAGING_DIR/lib/pkgconfig
OLDPATH="$PATH" OLDPATH="$PATH"
export PATH="$PATH:$TOOLCHAINS/$TARGET/bin" export PATH="$PATH:$TOOLCHAINS/$TARGET/bin"
CPU=
CFLAGS_PIC=
LDFLAGS_PIE=-static
# not all archs support -static-pie. if does not support - it produces dynamic executable
# "-static -static-pie" causes segfaults
case $1 in
armv6-*)
CPU="-mthumb -msoft-float"
CFLAGS="$CPU $CFLAGS"
;;
mips*)
;;
*)
[ "$PIE" = 1 ] && {
CFLAGS_PIC=-fPIC
LDFLAGS_PIE="-static-pie"
}
esac
} }
buildenv_clear() buildenv_clear()
{ {
export PATH="$OLDPATH" TARGET= CC= LD= AR= NM= STRIP= STAGING_DIR= PKG_CONFIG_PATH= export PATH="$OLDPATH" TARGET= CC= LD= AR= NM= STRIP= STAGING_DIR= PKG_CONFIG_PATH=
@@ -249,7 +273,7 @@ translate_target()
aarch64-unknown-linux-musl) aarch64-unknown-linux-musl)
ZBINTARGET=linux-arm64 ZBINTARGET=linux-arm64
;; ;;
arm-unknown-linux-musleabi) armv6-unknown-linux-musleabi)
ZBINTARGET=linux-arm ZBINTARGET=linux-arm
;; ;;
x86_64-unknown-linux-musl) x86_64-unknown-linux-musl)

View File

@@ -3531,7 +3531,8 @@ Checks the [instance cutoff](#instance_cutoff) state for `desync.func_instance`
function apply_arg_prefix(desync) function apply_arg_prefix(desync)
``` ```
Performs substitution of argument values from `desync.arg` that start with `%` and `#`. Performs substitution of argument values from `desync.arg` that start with `%`, `#`, `\`.
Multiple calls are safe but do not update desync.arg if blobs were changed.
### apply_execution_plan ### apply_execution_plan
@@ -3540,6 +3541,8 @@ function apply_execution_plan(desync, instance)
``` ```
Copies the instance identification and its arguments from an [execution plan](#execution_plan) `instance` into the desync object, thereby recreating the desync state as if the `instance` were called directly by C code. Copies the instance identification and its arguments from an [execution plan](#execution_plan) `instance` into the desync object, thereby recreating the desync state as if the `instance` were called directly by C code.
With one exception : apply_arg_prefix is not applied because args can refer a blob created by previous conditionally executed instances.
The [execution plan](#execution_plan) is provided by the C function `execution_plan()` as an array of `instance` elements. The [execution plan](#execution_plan) is provided by the C function `execution_plan()` as an array of `instance` elements.
### verdict_aggregate ### verdict_aggregate
@@ -3558,6 +3561,7 @@ function plan_instance_execute_preapplied(desync, verdict, instance)
``` ```
Executes an [execution plan](#execution_plan) `instance`, taking into account the [instance cutoff](#instance_cutoff) and standard [payload](#in-profile-filters) and [range](#in-profile-filters) filters. Executes an [execution plan](#execution_plan) `instance`, taking into account the [instance cutoff](#instance_cutoff) and standard [payload](#in-profile-filters) and [range](#in-profile-filters) filters.
Calls apply_arg_prefix right before calling the instance.
Returns the aggregation of the current verdict and the `instance` verdict. Returns the aggregation of the current verdict and the `instance` verdict.
The "preapplied" version does not apply execution plan, allowing the calling code to do so. The "preapplied" version does not apply execution plan, allowing the calling code to do so.
@@ -4479,6 +4483,7 @@ function cond_lua(desync)
``` ```
Executes a Lua code from the "cond_code" argument. The code returns condition value. Direct addressing of the desync table is possible within the code. Executes a Lua code from the "cond_code" argument. The code returns condition value. Direct addressing of the desync table is possible within the code.
desync.arg is passed without called "apply_arg_prefix" : `%`, `#`, `\` remain as is without substitution because can refer blobs created by previous conditionally executed instances.
# Auxiliary programs # Auxiliary programs

View File

@@ -3709,7 +3709,8 @@ function cutoff_shim_check(desync)
function apply_arg_prefix(desync) function apply_arg_prefix(desync)
``` ```
Выполняет подстановку значений аргументов из desync.arg, начинающихся с `%` и `#`. Выполняет подстановку значений аргументов из desync.arg, начинающихся с `%` и `#`, `\`.
Функция ставит специальную метку в desync.arg , чтобы избежать двойного разименования. Повторные вызовы безопасны, но не обновляют desync.arg при изменении блобов.
### apply_execution_plan ### apply_execution_plan
@@ -3719,6 +3720,8 @@ function apply_execution_plan(desync, instance)
Копирует в desync идентификацию инстанса и его аргументы из элемента [execution plan](#execution_plan) `instance`, Копирует в desync идентификацию инстанса и его аргументы из элемента [execution plan](#execution_plan) `instance`,
тем самым воссоздает состояние desync, как если бы `instance` был вызван напрямую C кодом. тем самым воссоздает состояние desync, как если бы `instance` был вызван напрямую C кодом.
За одним исключением : apply_arg_prefix не применяется, поскольку может содержать несуществующие блоб, существование которого зависит от условного выполнения предыдущих истансов.
[execution plan](#execution_plan) выдается C функцией `execution_plan()` как массив, элементами которого являются `instance`. [execution plan](#execution_plan) выдается C функцией `execution_plan()` как массив, элементами которого являются `instance`.
### verdict_aggregate ### verdict_aggregate
@@ -3737,6 +3740,7 @@ function plan_instance_execute_preapplied(desync, verdict, instance)
``` ```
Выполняет элемент [execution plan](#execution_plan) `instance` с учетом [instance cutoff](#instance_cutoff) и стандартных фильтров [payload](#внутрипрофильные-фильтры) и [range](#внутрипрофильные-фильтры). Выполняет элемент [execution plan](#execution_plan) `instance` с учетом [instance cutoff](#instance_cutoff) и стандартных фильтров [payload](#внутрипрофильные-фильтры) и [range](#внутрипрофильные-фильтры).
При совпадении условий непосредственно перед вызовом выполняет apply_arg_prefix.
Возвращает агрегацию verdict и вердикта `instance`. Возвращает агрегацию verdict и вердикта `instance`.
Вариант "preapplied" не выполняет apply_execution_plan, позволяя это сделат вызывающему коду. Вариант "preapplied" не выполняет apply_execution_plan, позволяя это сделат вызывающему коду.
@@ -4658,6 +4662,7 @@ function cond_lua(desync)
``` ```
Выполняет Lua код из аргумента "cond_code". Код возвращает значение условия через return. Возможна прямая адресация таблицы desync. Выполняет Lua код из аргумента "cond_code". Код возвращает значение условия через return. Возможна прямая адресация таблицы desync.
desync.arg передаются с НЕ разименованными `%`, `#`, `\`, поскольку разименование может ссылаться на блобы, создаваемые предыдущими условно вызываемыми инстансами.
# Вспомогательные программы # Вспомогательные программы

View File

@@ -414,8 +414,8 @@ nfqws2 \
### Какие есть еще параметры ### Какие есть еще параметры
Как узнать какие есть еще функции и какие у них бывают параметры ? Смотрите `zapret-antidpi.lua`. Перед каждой функцией подробно описано какие параметры она берет. Как узнать какие есть еще функции и какие у них бывают параметры ? Смотрите `zapret-antidpi.lua`. Перед каждой функцией подробно описано какие параметры она берет.
Описание стандартных блоков параметров есть в начале. Позже - по мере сил и возможностей - будет писаться талмуд - справочник с руководством по программированию Описание стандартных блоков параметров есть в начале.
*nfqws2* и описание стандартных библиотек. Или сразу читайте [талмуд](manual.md) . Там все документировано.
### Очень важный совет ### Очень важный совет

View File

@@ -1,13 +0,0 @@
REGISTER sip:192.168.1.1 SIP/2.0
Via: SIP/2.0/UDP 192.168.1.2:42931;rport;branch=z9hG4bKPj3fd2e8713ffcd90c43f6ce69f6c98461
Max-Forwards: 50
From: <sip:703@192.168.1.1>;tag=ca565d7bd4e24a6d80c631d395ee117e
To: <sip:703@192.168.1.1>
Call-ID: dfec38302b8cea3d83c1452527c895c1
CSeq: 26139 REGISTER
User-Agent: MicroSIP/3.21.5
Contact: <sip:703@192.168.1.2:42931;ob>
Expires: 300
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Content-Length: 0

View File

@@ -2,8 +2,8 @@
WEBSERVER_DEFAULT_STRATEGY=" WEBSERVER_DEFAULT_STRATEGY="
--server --server
--payload http_reply,tls_server_hello --lua-desync=fake:blob=0x00000000000000000000000000000000:badsum:repeats=2 --lua-desync=multisplit --payload=http_reply,tls_server_hello --lua-desync=fake:blob=0x00000000000000000000000000000000:badsum:repeats=2 --lua-desync=multisplit
--payload empty --lua-desync=synack_split" --payload=empty --lua-desync=synack_split"
# can override in config : # can override in config :
NFQWS_OPT_DESYNC_WEBSERVER="${NFQWS_OPT_DESYNC_WEBSERVER:-$WEBSERVER_DEFAULT_STRATEGY}" NFQWS_OPT_DESYNC_WEBSERVER="${NFQWS_OPT_DESYNC_WEBSERVER:-$WEBSERVER_DEFAULT_STRATEGY}"

View File

@@ -2,7 +2,7 @@
# NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22) # NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22)
# can override in config : # can override in config :
NFQWS_OPT_DESYNC_DHT="${NFQWS_OPT_DESYNC_DHT:---payload dht --lua-desync=dht_dn}" NFQWS_OPT_DESYNC_DHT="${NFQWS_OPT_DESYNC_DHT:---payload=dht --lua-desync=dht_dn}"
# set it to "keepalive" to fool all packets, not just the first. or set number of packets to be fooled. # set it to "keepalive" to fool all packets, not just the first. or set number of packets to be fooled.
NFQWS_OPT_DHT_PKT_OUT=${NFQWS_OPT_DHT_PKT_OUT:-20} NFQWS_OPT_DHT_PKT_OUT=${NFQWS_OPT_DHT_PKT_OUT:-20}

View File

@@ -2,7 +2,7 @@
# NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22) # NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22)
# can override in config : # can override in config :
NFQWS_OPT_DESYNC_DISCORD_MEDIA="${NFQWS_OPT_DESYNC_DISCORD_MEDIA:---payload discord_ip_discovery --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2}" NFQWS_OPT_DESYNC_DISCORD_MEDIA="${NFQWS_OPT_DESYNC_DISCORD_MEDIA:---payload=discord_ip_discovery --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2}"
DISCORD_MEDIA_PORT_RANGE="${DISCORD_MEDIA_PORT_RANGE:-50000-50099}" DISCORD_MEDIA_PORT_RANGE="${DISCORD_MEDIA_PORT_RANGE:-50000-50099}"
alloc_dnum DNUM_DISCORD_MEDIA alloc_dnum DNUM_DISCORD_MEDIA

View File

@@ -1,7 +1,7 @@
# this custom script demonstrates how to launch extra nfqws instance limited by ipset # this custom script demonstrates how to launch extra nfqws instance limited by ipset
# can override in config : # can override in config :
NFQWS2_MY1_OPT="${NFQWS2_MY1_OPT:---filter-udp=* --payload known,unknown --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2:payload=all --new --filter-tcp=* --payload=known,unknown --lua-desync=multisplit}" NFQWS2_MY1_OPT="${NFQWS2_MY1_OPT:---filter-udp=* --payload=known,unknown --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2:payload=all --new --filter-tcp=* --payload=known,unknown --lua-desync=multisplit}"
NFQWS2_MY1_SUBNETS4="${NFQWS2_MY1_SUBNETS4:-173.194.0.0/16 108.177.0.0/17 74.125.0.0/16 64.233.160.0/19 172.217.0.0/16}" NFQWS2_MY1_SUBNETS4="${NFQWS2_MY1_SUBNETS4:-173.194.0.0/16 108.177.0.0/17 74.125.0.0/16 64.233.160.0/19 172.217.0.0/16}"
NFQWS2_MY1_SUBNETS6="${NFQWS2_MY1_SUBNETS6:-2a00:1450::/29}" NFQWS2_MY1_SUBNETS6="${NFQWS2_MY1_SUBNETS6:-2a00:1450::/29}"
NFQWS2_MY1_PORTS_TCP=${NFQWS2_MY1_PORTS_TCP:-$NFQWS2_PORTS_TCP} NFQWS2_MY1_PORTS_TCP=${NFQWS2_MY1_PORTS_TCP:-$NFQWS2_PORTS_TCP}

View File

@@ -2,7 +2,7 @@
# NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22) # NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22)
# can override in config : # can override in config :
NFQWS_OPT_DESYNC_QUIC="${NFQWS_OPT_DESYNC_QUIC:---payload quic_initial --lua-desync=fake:blob=fake_default_quic:repeats=2}" NFQWS_OPT_DESYNC_QUIC="${NFQWS_OPT_DESYNC_QUIC:---payload=quic_initial --lua-desync=fake:blob=fake_default_quic:repeats=2}"
alloc_dnum DNUM_QUIC4ALL alloc_dnum DNUM_QUIC4ALL
alloc_qnum QNUM_QUIC4ALL alloc_qnum QNUM_QUIC4ALL

View File

@@ -2,7 +2,7 @@
# NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22) # NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22)
# can override in config : # can override in config :
NFQWS_OPT_DESYNC_STUN="${NFQWS_OPT_DESYNC_STUN:---payload stun --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2}" NFQWS_OPT_DESYNC_STUN="${NFQWS_OPT_DESYNC_STUN:---payload=stun --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2}"
alloc_dnum DNUM_STUN4ALL alloc_dnum DNUM_STUN4ALL
alloc_qnum QNUM_STUN4ALL alloc_qnum QNUM_STUN4ALL

View File

@@ -3,7 +3,7 @@
# NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22) # NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22)
# can override in config : # can override in config :
NFQWS_OPT_DESYNC_WG="${NFQWS_OPT_DESYNC_WG:---payload wireguard_initiation,wireguard_response,wireguard_cookie --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2}" NFQWS_OPT_DESYNC_WG="${NFQWS_OPT_DESYNC_WG:---payload=wireguard_initiation,wireguard_response,wireguard_cookie --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2}"
alloc_dnum DNUM_WG4ALL alloc_dnum DNUM_WG4ALL
alloc_qnum QNUM_WG4ALL alloc_qnum QNUM_WG4ALL

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/zapret2/init.d/sysv/zapret2 start ExecStart=/opt/zapret2/init.d/sysv/zapret2 start

View File

@@ -1,8 +1,12 @@
CC ?= cc CC ?= cc
OPTIMIZE ?= -Os OPTIMIZE ?= -Os
CFLAGS += -std=gnu99 $(OPTIMIZE) -flto=auto CFLAGS_PIC = -fPIC
CFLAGS += -std=gnu99 $(OPTIMIZE) -flto=auto $(CFLAGS_PIC)
CFLAGS_BSD = -Wno-address-of-packed-member CFLAGS_BSD = -Wno-address-of-packed-member
CFLAGS_WIN = -static CFLAGS_WIN = -static
LDFLAGS_PIE = -pie
LDFLAGS += $(LDFLAGS_PIE)
LIBS = LIBS =
LIBS_WIN = -lws2_32 LIBS_WIN = -lws2_32
SRC_FILES = ip2net.c qsort.c SRC_FILES = ip2net.c qsort.c

View File

@@ -125,7 +125,7 @@ function http_domcase(ctx, desync)
local host_range = resolve_multi_pos(desync.dis.payload,desync.l7payload,"host,endhost") local host_range = resolve_multi_pos(desync.dis.payload,desync.l7payload,"host,endhost")
if #host_range == 2 then if #host_range == 2 then
local host = string.sub(desync.dis.payload,host_range[1],host_range[2]-1) local host = string.sub(desync.dis.payload,host_range[1],host_range[2]-1)
local newhost="", i local newhost=""
for i = 1, #host do for i = 1, #host do
newhost=newhost..((i%2)==0 and string.lower(string.sub(host,i,i)) or string.upper(string.sub(host,i,i))) newhost=newhost..((i%2)==0 and string.lower(string.sub(host,i,i)) or string.upper(string.sub(host,i,i)))
end end
@@ -221,7 +221,7 @@ function http_unixeol(ctx, desync)
if #http < #desync.dis.payload then if #http < #desync.dis.payload then
hdis.headers[idx_ua].value = hdis.headers[idx_ua].value .. string.rep(" ", #desync.dis.payload - #http) hdis.headers[idx_ua].value = hdis.headers[idx_ua].value .. string.rep(" ", #desync.dis.payload - #http)
end end
local http = http_reconstruct_req(hdis, true) http = http_reconstruct_req(hdis, true)
if #http==#desync.dis.payload then if #http==#desync.dis.payload then
desync.dis.payload = http desync.dis.payload = http
DLOG("http_unixeol: applied") DLOG("http_unixeol: applied")
@@ -389,7 +389,8 @@ function syndata(ctx, desync)
dis.payload = blob(desync, desync.arg.blob, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") dis.payload = blob(desync, desync.arg.blob, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
apply_fooling(desync, dis) apply_fooling(desync, dis)
if desync.arg.tls_mod then if desync.arg.tls_mod then
dis.payload = tls_mod_shim(desync, dis.payload, desync.arg.tls_mod, nil) local pl = tls_mod_shim(desync, dis.payload, desync.arg.tls_mod, nil)
if pl then dis.payload = pl end
end end
if b_debug then DLOG("syndata: "..hexdump_dlog(dis.payload)) end if b_debug then DLOG("syndata: "..hexdump_dlog(dis.payload)) end
if rawsend_dissect_ipfrag(dis, desync_opts(desync)) then if rawsend_dissect_ipfrag(dis, desync_opts(desync)) then
@@ -449,7 +450,8 @@ function fake(ctx, desync)
end end
local fake_payload = blob(desync, desync.arg.blob) local fake_payload = blob(desync, desync.arg.blob)
if desync.reasm_data and desync.arg.tls_mod then if desync.reasm_data and desync.arg.tls_mod then
fake_payload = tls_mod_shim(desync, fake_payload, desync.arg.tls_mod, desync.reasm_data) local pl = tls_mod_shim(desync, fake_payload, desync.arg.tls_mod, desync.reasm_data)
if pl then fake_payload = pl end
end end
-- check debug to save CPU -- check debug to save CPU
if b_debug then DLOG("fake: "..hexdump_dlog(fake_payload)) end if b_debug then DLOG("fake: "..hexdump_dlog(fake_payload)) end
@@ -729,14 +731,15 @@ function hostfakesplit(ctx, desync)
local midhost local midhost
if desync.arg.midhost then if desync.arg.midhost then
midhost = resolve_pos(data,desync.l7payload,desync.arg.midhost) midhost = resolve_pos(data,desync.l7payload,desync.arg.midhost)
if not midhost then if midhost then
DLOG("hosfakesplit: midhost marker resolved to "..midhost)
if midhost<=pos[1] or midhost>pos[2] then
DLOG("hostfakesplit: midhost is not inside the host range")
midhost = nil
end
else
DLOG("hostfakesplit: cannot resolve midhost marker '"..desync.arg.midhost.."'") DLOG("hostfakesplit: cannot resolve midhost marker '"..desync.arg.midhost.."'")
end end
DLOG("hosfakesplit: midhost marker resolved to "..midhost)
if midhost<=pos[1] or midhost>pos[2] then
DLOG("hostfakesplit: midhost is not inside the host range")
midhost = nil
end
end end
-- if present apply ipfrag only to real host parts. fakes and parts outside of the host must be visible to DPI. -- if present apply ipfrag only to real host parts. fakes and parts outside of the host must be visible to DPI.
if midhost then if midhost then
@@ -893,7 +896,7 @@ function fakedsplit(ctx, desync)
return desync.arg.nodrop and VERDICT_PASS or VERDICT_DROP return desync.arg.nodrop and VERDICT_PASS or VERDICT_DROP
end end
else else
DLOG("fakedsplit: cannot resolve pos '"..desync.arg.pos.."'") DLOG("fakedsplit: cannot resolve pos '"..spos.."'")
end end
else else
DLOG("fakedsplit: not acting on further replay pieces") DLOG("fakedsplit: not acting on further replay pieces")
@@ -938,11 +941,11 @@ function fakeddisorder(ctx, desync)
if b_debug then DLOG("fakeddisorder: resolved split pos: "..tostring(pos-1)) end if b_debug then DLOG("fakeddisorder: resolved split pos: "..tostring(pos-1)) end
-- do not apply fooling to original parts except tcp_ts_up but apply ip_id -- do not apply fooling to original parts except tcp_ts_up but apply ip_id
local fake, part, pat local fake, part
local opts_orig = {rawsend = rawsend_opts_base(desync), reconstruct = {}, ipfrag = {}, ipid = desync.arg, fooling = {tcp_ts_up = desync.arg.tcp_ts_up}} local opts_orig = {rawsend = rawsend_opts_base(desync), reconstruct = {}, ipfrag = {}, ipid = desync.arg, fooling = {tcp_ts_up = desync.arg.tcp_ts_up}}
local opts_fake = {rawsend = rawsend_opts(desync), reconstruct = reconstruct_opts(desync), ipfrag = {}, ipid = desync.arg, fooling = desync.arg} local opts_fake = {rawsend = rawsend_opts(desync), reconstruct = reconstruct_opts(desync), ipfrag = {}, ipid = desync.arg, fooling = desync.arg}
fakepat = desync.arg.pattern and blob(desync,desync.arg.pattern) or "\x00" local fakepat = desync.arg.pattern and blob(desync,desync.arg.pattern) or "\x00"
-- second fake -- second fake
fake = pattern(fakepat,pos,#data-pos+1) fake = pattern(fakepat,pos,#data-pos+1)
@@ -1008,7 +1011,7 @@ function fakeddisorder(ctx, desync)
return desync.arg.nodrop and VERDICT_PASS or VERDICT_DROP return desync.arg.nodrop and VERDICT_PASS or VERDICT_DROP
end end
else else
DLOG("fakeddisorder: cannot resolve pos '"..desync.arg.pos.."'") DLOG("fakeddisorder: cannot resolve pos '"..spos.."'")
end end
else else
DLOG("fakeddisorder: not acting on further replay pieces") DLOG("fakeddisorder: not acting on further replay pieces")
@@ -1209,8 +1212,8 @@ function udplen(ctx, desync)
else else
desync.dis.payload = string.sub(desync.dis.payload,1,len+inc) desync.dis.payload = string.sub(desync.dis.payload,1,len+inc)
DLOG("udplen: "..len.." => "..#desync.dis.payload) DLOG("udplen: "..len.." => "..#desync.dis.payload)
return VERDICT_MODIFY
end end
return VERDICT_MODIFY
end end
end end
end end

View File

@@ -313,7 +313,7 @@ function circular(ctx, desync)
local function count_strategies(hrec) local function count_strategies(hrec)
if not hrec.ctstrategy then if not hrec.ctstrategy then
local uniq={} local uniq={}
local n=0 local n
for i,instance in pairs(desync.plan) do for i,instance in pairs(desync.plan) do
if instance.arg.strategy then if instance.arg.strategy then
n = tonumber(instance.arg.strategy) n = tonumber(instance.arg.strategy)

View File

@@ -96,12 +96,12 @@ function detect_payload_str(ctx, desync)
error("detect_payload_str: missing 'pattern'") error("detect_payload_str: missing 'pattern'")
end end
local data = desync.reasm_data or desync.dis.payload local data = desync.reasm_data or desync.dis.payload
local b = string.find(data,desync.arg.pattern,1,true) local b = data and string.find(data,desync.arg.pattern,1,true)
if b then if b then
DLOG("detect_payload_str: detected '"..desync.arg.payload.."'") DLOG("detect_payload_str: detected '"..(desync.arg.payload or '?').."'")
if desync.arg.payload then desync.l7payload = desync.arg.payload end if desync.arg.payload then desync.l7payload = desync.arg.payload end
else else
DLOG("detect_payload_str: not detected '"..desync.arg.payload.."'") DLOG("detect_payload_str: not detected '"..(desync.arg.payload or '?').."'")
if desync.arg.undetected then desync.l7payload = desync.arg.undetected end if desync.arg.undetected then desync.l7payload = desync.arg.undetected end
end end
end end
@@ -149,11 +149,13 @@ end
-- applies # and $ prefixes. #var means var length, %var means var value -- applies # and $ prefixes. #var means var length, %var means var value
function apply_arg_prefix(desync) function apply_arg_prefix(desync)
-- prevent double apply
if desync.arg.__prefix_applied then return end
for a,v in pairs(desync.arg) do for a,v in pairs(desync.arg) do
local c = string.sub(v,1,1) local c = string.sub(v,1,1)
if c=='#' then if c=='#' then
local blb = blob(desync,string.sub(v,2)) local blb = blob(desync,string.sub(v,2))
desync.arg[a] = tostring((type(blb)=='string' or type(blb)=='table') and #blb or 0) desync.arg[a] = tostring(type(blb)=='string' and #blb or 0)
elseif c=='%' then elseif c=='%' then
desync.arg[a] = blob(desync,string.sub(v,2)) desync.arg[a] = blob(desync,string.sub(v,2))
elseif c=='\\' then elseif c=='\\' then
@@ -163,6 +165,7 @@ function apply_arg_prefix(desync)
end end
end end
end end
desync.arg.__prefix_applied = true
end end
-- copy instance identification and args from execution plan to desync table -- copy instance identification and args from execution plan to desync table
-- NOTE : to not lose VERDICT_MODIFY dissect changes pass original desync table -- NOTE : to not lose VERDICT_MODIFY dissect changes pass original desync table
@@ -173,7 +176,7 @@ function apply_execution_plan(desync, instance)
desync.func_n = instance.func_n desync.func_n = instance.func_n
desync.func_instance = instance.func_instance desync.func_instance = instance.func_instance
desync.arg = deepcopy(instance.arg) desync.arg = deepcopy(instance.arg)
apply_arg_prefix(desync) -- no apply_arg_prefix here because it may refer non-existing blobs
end end
-- produce resulting verdict from 2 verdicts -- produce resulting verdict from 2 verdicts
function verdict_aggregate(v1, v2) function verdict_aggregate(v1, v2)
@@ -200,6 +203,9 @@ function plan_instance_execute_preapplied(desync, verdict, instance)
elseif not pos_check_range(desync, instance.range) then elseif not pos_check_range(desync, instance.range) then
DLOG("plan_instance_execute: not calling '"..desync.func_instance.."' because pos "..pos_str(desync,instance.range.from).." "..pos_str(desync,instance.range.to).." is out of range '"..pos_range_str(instance.range).."'") DLOG("plan_instance_execute: not calling '"..desync.func_instance.."' because pos "..pos_str(desync,instance.range.from).." "..pos_str(desync,instance.range.to).." is out of range '"..pos_range_str(instance.range).."'")
else else
-- condition is satisfied. here blobs must be referenced
apply_arg_prefix(desync)
desync.arg.__prefix_applied = nil
DLOG("plan_instance_execute: calling '"..desync.func_instance.."'") DLOG("plan_instance_execute: calling '"..desync.func_instance.."'")
verdict = verdict_aggregate(verdict,_G[instance.func](nil, desync)) verdict = verdict_aggregate(verdict,_G[instance.func](nil, desync))
end end
@@ -337,9 +343,8 @@ end
-- convert array a to packed string using 'packer' function. only numeric indexes starting from 1, order preserved -- convert array a to packed string using 'packer' function. only numeric indexes starting from 1, order preserved
function barray(a, packer) function barray(a, packer)
local sa={}
if a then if a then
local s="" local sa={}
for i=1,#a do for i=1,#a do
sa[i] = packer(a[i]) sa[i] = packer(a[i])
end end
@@ -348,16 +353,16 @@ function barray(a, packer)
end end
-- convert table a to packed string using 'packer' function. any indexes, any order -- convert table a to packed string using 'packer' function. any indexes, any order
function btable(a, packer) function btable(a, packer)
local sa={}
if a then if a then
local s="" local sa={}
local i=1
for k,v in pairs(a) do for k,v in pairs(a) do
sa[k] = packer(v) sa[i] = packer(v)
i=i+1
end end
return table.concat(sa) return table.concat(sa)
end end
end end
-- sequence comparision functions. they work only within 2G interval -- sequence comparision functions. they work only within 2G interval
-- seq1>=seq2 -- seq1>=seq2
function seq_ge(seq1, seq2) function seq_ge(seq1, seq2)
@@ -633,7 +638,7 @@ function tls_mod_shim(desync, blob, modlist, payload)
if not val then if not val then
error("tls_mod_shim: non-existent var '"..var.."'") error("tls_mod_shim: non-existent var '"..var.."'")
end end
modlist = string.sub(modlist,1,p1+3)..val..string.sub(modlist,p2+1) modlist = string.sub(modlist,1,p1+3)..tostring(val)..string.sub(modlist,p2+1)
end end
return tls_mod(blob,modlist,payload) return tls_mod(blob,modlist,payload)
end end
@@ -645,7 +650,7 @@ function parse_tcp_flags(s)
local s_upper = string.upper(s) local s_upper = string.upper(s)
for flag in string.gmatch(s_upper, "[^,]+") do for flag in string.gmatch(s_upper, "[^,]+") do
if flags[flag] then if flags[flag] then
f = bitor(f,flags[flag]) f = bitor(f,flags[flag])
else else
error("tcp flag '"..flag.."' is invalid") error("tcp flag '"..flag.."' is invalid")
end end
@@ -876,7 +881,11 @@ function apply_fooling(desync, dis, fooling_options)
if type(desync.track.lua_state.autottl_cache)~="table" then desync.track.lua_state.autottl_cache={} end if type(desync.track.lua_state.autottl_cache)~="table" then desync.track.lua_state.autottl_cache={} end
if type(desync.track.lua_state.autottl_cache[desync.func_instance])~="table" then desync.track.lua_state.autottl_cache[desync.func_instance]={} end if type(desync.track.lua_state.autottl_cache[desync.func_instance])~="table" then desync.track.lua_state.autottl_cache[desync.func_instance]={} end
if not desync.track.lua_state.autottl_cache[desync.func_instance].autottl_found then if not desync.track.lua_state.autottl_cache[desync.func_instance].autottl_found then
desync.track.lua_state.autottl_cache[desync.func_instance].autottl = autottl(desync.track.incoming_ttl,parse_autottl(arg_autottl)) local attl = parse_autottl(arg_autottl)
if not attl then
error("apply_fooling: invalid autottl value '"..arg_autottl.."'")
end
desync.track.lua_state.autottl_cache[desync.func_instance].autottl = autottl(desync.track.incoming_ttl,attl)
if desync.track.lua_state.autottl_cache[desync.func_instance].autottl then if desync.track.lua_state.autottl_cache[desync.func_instance].autottl then
desync.track.lua_state.autottl_cache[desync.func_instance].autottl_found = true desync.track.lua_state.autottl_cache[desync.func_instance].autottl_found = true
DLOG("apply_fooling: discovered autottl "..desync.track.lua_state.autottl_cache[desync.func_instance].autottl) DLOG("apply_fooling: discovered autottl "..desync.track.lua_state.autottl_cache[desync.func_instance].autottl)
@@ -891,8 +900,11 @@ function apply_fooling(desync, dis, fooling_options)
DLOG("apply_fooling: cannot apply autottl because incoming ttl unknown") DLOG("apply_fooling: cannot apply autottl because incoming ttl unknown")
end end
end end
if not ttl and tonumber(arg_ttl) then if not ttl and arg_ttl then
ttl = tonumber(arg_ttl) ttl = tonumber(arg_ttl)
if not ttl or ttl<0 or ttl>255 then
error("apply_fooling: ip_ttl and ip6_ttl require valid value")
end
end end
--io.stderr:write("TTL "..tostring(ttl).."\n") --io.stderr:write("TTL "..tostring(ttl).."\n")
return ttl return ttl
@@ -909,11 +921,19 @@ function apply_fooling(desync, dis, fooling_options)
-- use current packet if dissect not given -- use current packet if dissect not given
if not dis then dis = desync.dis end if not dis then dis = desync.dis end
if dis.tcp then if dis.tcp then
if tonumber(fooling_options.tcp_seq) then if fooling_options.tcp_seq then
dis.tcp.th_seq = u32add(dis.tcp.th_seq, fooling_options.tcp_seq) if tonumber(fooling_options.tcp_seq) then
dis.tcp.th_seq = u32add(dis.tcp.th_seq, fooling_options.tcp_seq)
else
error("apply_fooling: tcp_seq requires increment parameter. there's no default value.")
end
end end
if tonumber(fooling_options.tcp_ack) then if fooling_options.tcp_ack then
dis.tcp.th_ack = u32add(dis.tcp.th_ack, fooling_options.tcp_ack) if tonumber(fooling_options.tcp_ack) then
dis.tcp.th_ack = u32add(dis.tcp.th_ack, fooling_options.tcp_ack)
else
error("apply_fooling: tcp_ack requires increment parameter. there's no default value.")
end
end end
if fooling_options.tcp_flags_unset then if fooling_options.tcp_flags_unset then
dis.tcp.th_flags = bitand(dis.tcp.th_flags, bitnot(parse_tcp_flags(fooling_options.tcp_flags_unset))) dis.tcp.th_flags = bitand(dis.tcp.th_flags, bitnot(parse_tcp_flags(fooling_options.tcp_flags_unset)))
@@ -928,12 +948,16 @@ function apply_fooling(desync, dis, fooling_options)
end end
end end
end end
if tonumber(fooling_options.tcp_ts) then if fooling_options.tcp_ts then
local idx = find_tcp_option(dis.tcp.options,TCP_KIND_TS) if tonumber(fooling_options.tcp_ts) then
if idx and (dis.tcp.options[idx].data and #dis.tcp.options[idx].data or 0)==8 then local idx = find_tcp_option(dis.tcp.options,TCP_KIND_TS)
dis.tcp.options[idx].data = bu32(u32add(u32(dis.tcp.options[idx].data),fooling_options.tcp_ts))..string.sub(dis.tcp.options[idx].data,5) if idx and (dis.tcp.options[idx].data and #dis.tcp.options[idx].data or 0)==8 then
dis.tcp.options[idx].data = bu32(u32add(u32(dis.tcp.options[idx].data),fooling_options.tcp_ts))..string.sub(dis.tcp.options[idx].data,5)
else
DLOG("apply_fooling: timestamp tcp option not present or invalid")
end
else else
DLOG("apply_fooling: timestamp tcp option not present or invalid") error("apply_fooling: tcp_ts requires increment parameter. there's no default value.")
end end
end end
if fooling_options.tcp_md5 then if fooling_options.tcp_md5 then
@@ -944,7 +968,7 @@ function apply_fooling(desync, dis, fooling_options)
end end
end end
if fooling_options.tcp_ts_up then if fooling_options.tcp_ts_up then
move_ts_top(dis.tcp.options) move_ts_top()
end end
end end
if dis.ip6 then if dis.ip6 then
@@ -1183,7 +1207,7 @@ function rawsend_dissect_segmented(desync, dis, mss, options)
-- stop if failed -- stop if failed
return false return false
end end
discopy.tcp.th_seq = discopy.tcp.th_seq + len discopy.tcp.th_seq = u32add(discopy.tcp.th_seq, len)
pos = pos + len pos = pos + len
end end
return true return true
@@ -1548,11 +1572,11 @@ function tls_client_hello_mod(tls, options)
table.insert(tdis.handshake[TLS_HANDSHAKE_TYPE_CLIENT].dis.ext[idx_sni].dis.list, { name = options.sni_last, type = options.sni_snt_new } ) table.insert(tdis.handshake[TLS_HANDSHAKE_TYPE_CLIENT].dis.ext[idx_sni].dis.list, { name = options.sni_last, type = options.sni_snt_new } )
end end
end end
local tls = tls_reconstruct(tdis) local rtls = tls_reconstruct(tdis)
if not tls then if not rtls then
DLOG_ERR("tls_client_hello_mod: reconstruct error") DLOG_ERR("tls_client_hello_mod: reconstruct error")
end end
return tls return rtls
end end
-- checks if filename is gzip compressed -- checks if filename is gzip compressed
@@ -1619,9 +1643,9 @@ function gzip_file(filename, data, expected_ratio, level, memlevel, compress_blo
if not gz then if not gz then
error("gzip_file: stream init error") error("gzip_file: stream init error")
end end
local off=1, block_size local off=1
repeat repeat
block_size = #data-off+1 local block_size = #data-off+1
if block_size>compress_block_size then block_size=compress_block_size end if block_size>compress_block_size then block_size=compress_block_size end
local comp, eof = gzip_deflate(gz, string.sub(data,off,off+block_size-1), block_size / expected_ratio) local comp, eof = gzip_deflate(gz, string.sub(data,off,off+block_size-1), block_size / expected_ratio)
if not comp then if not comp then
@@ -1641,7 +1665,7 @@ function readfile(filename)
if not f then if not f then
error("readfile: "..err) error("readfile: "..err)
end end
local s,err = f:read("*a") local s, err = f:read("*a")
f:close() f:close()
if err then if err then
error("readfile: "..err) error("readfile: "..err)
@@ -1659,7 +1683,7 @@ function writefile(filename, data)
if not f then if not f then
error("writefile: "..err) error("writefile: "..err)
end end
local s,err = f:write(data) local s, err = f:write(data)
f:close() f:close()
if not s then if not s then
error("writefile: "..err) error("writefile: "..err)
@@ -1679,7 +1703,7 @@ function http_dissect_header(header)
end end
-- make table with structured http header representation -- make table with structured http header representation
function http_dissect_headers(http, pos) function http_dissect_headers(http, pos)
local eol,pnext,header,value,idx,headers,pos_endheader,pos_startvalue,pos_headers_end local eol,pnext,header,value,headers,pos_endheader,pos_startvalue,pos_headers_end
headers={} headers={}
while pos do while pos do
eol,pnext = find_next_line(http,pos) eol,pnext = find_next_line(http,pos)
@@ -2243,7 +2267,8 @@ function tls_dissect_ext(ext)
return left, off return left, off
end end
local dis={}, off, len, left local dis={}
local off, len, left
ext.dis = nil ext.dis = nil

View File

@@ -175,7 +175,12 @@ end
-- arg : server=[0|1] - override server mode. by default use "--server" nfqws2 parameter -- arg : server=[0|1] - override server mode. by default use "--server" nfqws2 parameter
function udp2icmp(ctx, desync) function udp2icmp(ctx, desync)
local dataxor local dataxor
local bserver = desync.arg.server and (desync.arg.server~="0") or b_server local bserver
if desync.arg.server then
bserver = desync.arg.server~="0"
else
bserver = b_server
end
local function one_byte_arg(name) local function one_byte_arg(name)
if desync.arg[name] then if desync.arg[name] then

View File

@@ -1,6 +1,6 @@
function pcap_write_header(file) function pcap_write_header(file)
-- big endian, nanoseconds in timestamps, ver 2.4, max packet size - 0x4000 (16384), 0x65 - l3 packets without l2 -- big endian, nanoseconds in timestamps, ver 2.4, max packet size - 0xFFFF (65535), 0x65 - l3 packets without l2
file:write("\xA1\xB2\x3C\x4D\x00\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x65") file:write("\xA1\xB2\x3C\x4D\x00\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x65")
end end
function pcap_write_packet(file, raw) function pcap_write_packet(file, raw)
local sec, nsec = clock_gettime(); local sec, nsec = clock_gettime();
@@ -8,7 +8,7 @@ function pcap_write_packet(file, raw)
file:write(raw) file:write(raw)
end end
function pcap_write(file, raw) function pcap_write(file, raw)
local pos = file:seek() local pos = file:seek('end')
if (pos==0) then if (pos==0) then
pcap_write_header(file) pcap_write_header(file)
end end
@@ -34,6 +34,7 @@ function pcap(ctx, desync)
if not f then if not f then
error("pcap: could not write to '".._G[fn_cache_name].."'") error("pcap: could not write to '".._G[fn_cache_name].."'")
end end
pcap_write(f, raw_packet(ctx)) local raw = ctx and raw_packet(ctx) or reconstruct_dissect(desync.dis)
pcap_write(f, raw)
f:close() f:close()
end end

View File

@@ -119,7 +119,7 @@ function test_aes()
print("* aes") print("* aes")
local clear_text="test "..brandom_az09(11) local clear_text="test "..brandom_az09(11)
local iv, key, encrypted, decrypted local encrypted, decrypted
for key_size=16,32,8 do for key_size=16,32,8 do
local key = brandom(key_size) local key = brandom(key_size)
@@ -507,7 +507,7 @@ end
function test_dissect() function test_dissect()
print("* dissect") print("* dissect")
local dis, raw1, raw2 local raw1, raw2
for i=1,20 do for i=1,20 do
print("* dissect test "..tostring(i)) print("* dissect test "..tostring(i))
@@ -611,7 +611,7 @@ function test_dissect()
}, },
payload = brandom(math.random(0, 20)) payload = brandom(math.random(0, 20))
} }
raw1 = reconstruct_dissect(ip6_udp) raw1 = reconstruct_dissect(ip6_udp)
print("IP6+UDP : "..string2hex(raw1)) print("IP6+UDP : "..string2hex(raw1))
dis1 = dissect(raw1) dis1 = dissect(raw1)
@@ -772,11 +772,6 @@ function test_csum()
uh_ulen = UDP_BASE_LEN + #payload uh_ulen = UDP_BASE_LEN + #payload
} }
ip.ip_p = IPPROTO_UDP
ip4b = reconstruct_iphdr(ip)
ip6.ip6_plen = packet_len({ip6=ip6,udp=udp,payload=payload}) - IP6_BASE_LEN
ip6b = reconstruct_ip6hdr(ip6, {ip6_last_proto=IPPROTO_UDP})
udpb = reconstruct_udphdr(udp) udpb = reconstruct_udphdr(udp)
raw = bu16(udp.uh_sport) .. raw = bu16(udp.uh_sport) ..
bu16(udp.uh_dport) .. bu16(udp.uh_dport) ..
@@ -785,8 +780,10 @@ function test_csum()
print( raw==udpb and "UDP RECONSTRUCT OK" or "UDP RECONSTRUCT FAILED" ) print( raw==udpb and "UDP RECONSTRUCT OK" or "UDP RECONSTRUCT FAILED" )
test_assert(raw==udpb) test_assert(raw==udpb)
ip.ip_p = IPPROTO_UDP
raw = reconstruct_dissect({ip=ip, udp=udp, payload=payload}) raw = reconstruct_dissect({ip=ip, udp=udp, payload=payload})
dis1 = dissect(raw) dis1 = dissect(raw)
ip.ip_p = IPPROTO_UDP
ip.ip_len = IP_BASE_LEN + #ip.options + #udpb + #payload ip.ip_len = IP_BASE_LEN + #ip.options + #udpb + #payload
ip4b = reconstruct_iphdr(ip) ip4b = reconstruct_iphdr(ip)
udpb = csum_udp_fix(ip4b,udpb,payload) udpb = csum_udp_fix(ip4b,udpb,payload)
@@ -794,6 +791,8 @@ function test_csum()
print( dis1.udp.uh_sum==dis2.udp.uh_sum and "UDP+IP4 CSUM OK" or "UDP+IP4 CSUM FAILED" ) print( dis1.udp.uh_sum==dis2.udp.uh_sum and "UDP+IP4 CSUM OK" or "UDP+IP4 CSUM FAILED" )
test_assert(dis1.udp.uh_sum==dis2.udp.uh_sum) test_assert(dis1.udp.uh_sum==dis2.udp.uh_sum)
ip6.ip6_plen = packet_len({ip6=ip6,udp=udp,payload=payload}) - IP6_BASE_LEN
ip6b = reconstruct_ip6hdr(ip6, {ip6_last_proto=IPPROTO_UDP})
raw = reconstruct_dissect({ip6=ip6, udp=udp, payload=payload}) raw = reconstruct_dissect({ip6=ip6, udp=udp, payload=payload})
dis1 = dissect(raw) dis1 = dissect(raw)
udpb = csum_udp_fix(ip6b,udpb,payload) udpb = csum_udp_fix(ip6b,udpb,payload)
@@ -949,7 +948,6 @@ function test_rawsend(opts)
end end
local ip, ip6, udp, dis, ddis, raw_ip, raw_udp, raw local ip, ip6, udp, dis, ddis, raw_ip, raw_udp, raw
local payload = brandom(math.random(100,1200)) local payload = brandom(math.random(100,1200))
local b
local target local target
for ifname,ifinfo in pairs(get_ifaddrs()) do for ifname,ifinfo in pairs(get_ifaddrs()) do
@@ -997,7 +995,6 @@ function test_rawsend(opts)
print("send ipv4 udp using pure rawsend without dissect") print("send ipv4 udp using pure rawsend without dissect")
test_assert(rawsend_print(raw, {repeats=5})) test_assert(rawsend_print(raw, {repeats=5}))
local target
for ifname,ifinfo in pairs(get_ifaddrs()) do for ifname,ifinfo in pairs(get_ifaddrs()) do
for k,v in pairs(ifinfo.addr) do for k,v in pairs(ifinfo.addr) do
if #v.addr==16 and (string.sub(v.addr,1,1)=="\xFC" or string.sub(v.addr,1,1)=="\xFD") then if #v.addr==16 and (string.sub(v.addr,1,1)=="\xFC" or string.sub(v.addr,1,1)=="\xFD") then
@@ -1083,7 +1080,7 @@ function test_rawsend(opts)
print("send ipv6 icmp") print("send ipv6 icmp")
test_assert(rawsend_dissect_print(dis, {fwmark = 0x8E10, repeats=3})) test_assert(rawsend_dissect_print(dis, {fwmark = 0x8E10, repeats=3}))
local ip2 = { ip2 = {
ip_tos = 0, ip_tos = 0,
ip_id = math.random(0,0xFFFF), ip_id = math.random(0,0xFFFF),
ip_off = 0, ip_off = 0,

View File

@@ -1,8 +1,11 @@
CC ?= cc CC ?= cc
OPTIMIZE ?= -Os OPTIMIZE ?= -Os
CFLAGS += -std=gnu99 $(OPTIMIZE) CFLAGS_PIC = -fPIC
CFLAGS += -std=gnu99 $(OPTIMIZE) $(CFLAGS_PIC)
CFLAGS_BSD = -Wno-address-of-packed-member CFLAGS_BSD = -Wno-address-of-packed-member
CFLAGS_WIN = -static CFLAGS_WIN = -static
LDFLAGS_PIE = -pie
LDFLAGS += $(LDFLAGS_PIE)
LIBS = -lpthread LIBS = -lpthread
LIBS_ANDROID = LIBS_ANDROID =
LIBS_WIN = -lws2_32 LIBS_WIN = -lws2_32

View File

@@ -2,8 +2,11 @@ CC ?= cc
PKG_CONFIG ?= pkg-config PKG_CONFIG ?= pkg-config
OPTIMIZE ?= -Oz OPTIMIZE ?= -Oz
MINSIZE ?= -flto=auto -ffunction-sections -fdata-sections MINSIZE ?= -flto=auto -ffunction-sections -fdata-sections
CFLAGS += -std=gnu99 -s $(OPTIMIZE) $(MINSIZE) -Wno-address-of-packed-member STRIPP = -s
LDFLAGS += -flto=auto -Wl,--gc-sections CFLAGS_PIC = -fPIC
CFLAGS += -std=gnu99 $(OPTIMIZE) $(MINSIZE) $(CFLAGS_PIC) -Wno-address-of-packed-member
LDFLAGS_PIE = -pie
LDFLAGS += -flto=auto -Wl,--gc-sections $(LDFLAGS_PIE)
LIBS = -lz -lm LIBS = -lz -lm
SRC_FILES = *.c crypto/*.c SRC_FILES = *.c crypto/*.c
@@ -39,7 +42,7 @@ LUA_CFLAGS+=-DLUAJIT
all: dvtws2 all: dvtws2
dvtws2: $(SRC_FILES) dvtws2: $(SRC_FILES)
$(CC) $(CFLAGS) $(LUA_CFLAGS) -o dvtws2 $(SRC_FILES) $(LIBS) $(LUA_LIB) $(LDFLAGS) $(CC) $(STRIPP) $(CFLAGS) $(LUA_CFLAGS) -o dvtws2 $(SRC_FILES) $(LIBS) $(LUA_LIB) $(LDFLAGS)
clean: clean:
rm -f dvtws2 rm -f dvtws2

View File

@@ -3,14 +3,19 @@ PKG_CONFIG ?= pkg-config
OPTIMIZE ?= -Os OPTIMIZE ?= -Os
MINSIZE ?= -flto=auto -ffunction-sections -fdata-sections MINSIZE ?= -flto=auto -ffunction-sections -fdata-sections
CFLAGS += -std=gnu99 $(OPTIMIZE) $(MINSIZE) CFLAGS += -std=gnu99 $(OPTIMIZE) $(MINSIZE)
CFLAGS_LINUX = -Wno-alloc-size-larger-than CFLAGS_PIC = -fPIC
CFLAGS_LINUX = -Wno-alloc-size-larger-than $(CFLAGS_PIC)
CFLAGS_SYSTEMD = -DUSE_SYSTEMD CFLAGS_SYSTEMD = -DUSE_SYSTEMD
CFLAGS_BSD = -Wno-address-of-packed-member CFLAGS_BSD = -Wno-address-of-packed-member $(CFLAGS_PIC)
CFLAGS_CYGWIN = -Wno-address-of-packed-member -static CFLAGS_CYGWIN = -Wno-address-of-packed-member -static -Wl,--nxcompat
CFLAGS_CYGWIN32 = CFLAGS_CYGWIN32 =
CFLAGS_CYGWIN64 = -Wl,--dynamicbase -Wl,--high-entropy-va
CFLAGS_UBSAN = -fsanitize=undefined,alignment -fno-sanitize-recover=undefined,alignment CFLAGS_UBSAN = -fsanitize=undefined,alignment -fno-sanitize-recover=undefined,alignment
LDFLAGS += -flto=auto -Wl,--gc-sections LDFLAGS_PIE = -pie
LDFLAGS += -flto=auto -Wl,--gc-sections $(LDFLAGS_PIE)
LDFLAGS_ANDROID = -llog LDFLAGS_ANDROID = -llog
LDFLAGS_CYGWIN = -Wl,--build-id=none
STRIPP=-s
LIBS = LIBS =
LIBS_LINUX = -lz -lnetfilter_queue -lnfnetlink -lmnl -lm LIBS_LINUX = -lz -lnetfilter_queue -lnfnetlink -lmnl -lm
LIBS_SYSTEMD = -lsystemd LIBS_SYSTEMD = -lsystemd
@@ -138,24 +143,24 @@ LUA_CFL += $(LUA_CFLAGS)
all: nfqws2 all: nfqws2
nfqws2: $(SRC_FILES) nfqws2: $(SRC_FILES)
$(CC) -s $(CFLAGS) $(LUA_CFL) $(CFLAGS_LINUX) -o nfqws2 $(SRC_FILES) $(LIBS) $(LUA_LIB) $(LIBS_LINUX) $(LDFLAGS) $(CC) $(STRIPP) $(CFLAGS) $(LUA_CFL) $(CFLAGS_LINUX) -o nfqws2 $(SRC_FILES) $(LIBS) $(LUA_LIB) $(LIBS_LINUX) $(LDFLAGS)
ubsan: $(SRC_FILES) ubsan: $(SRC_FILES)
$(CC) $(CFLAGS_UBSAN) $(CFLAGS) $(LUA_CFL) $(CFLAGS_LINUX) -o nfqws2 $(SRC_FILES) $(LIBS) $(LUA_LIB) $(LIBS_LINUX) $(LDFLAGS) $(CC) $(CFLAGS_UBSAN) $(CFLAGS) $(LUA_CFL) $(CFLAGS_LINUX) -o nfqws2 $(SRC_FILES) $(LIBS) $(LUA_LIB) $(LIBS_LINUX) $(LDFLAGS)
systemd: $(SRC_FILES) systemd: $(SRC_FILES)
$(CC) -s $(CFLAGS) $(LUA_CFL) $(CFLAGS_LINUX) $(CFLAGS_SYSTEMD) -o nfqws2 $(SRC_FILES) $(LIBS) $(LUA_LIB) $(LIBS_LINUX) $(LIBS_SYSTEMD) $(LDFLAGS) $(CC) $(STRIPP) $(CFLAGS) $(LUA_CFL) $(CFLAGS_LINUX) $(CFLAGS_SYSTEMD) -o nfqws2 $(SRC_FILES) $(LIBS) $(LUA_LIB) $(LIBS_LINUX) $(LIBS_SYSTEMD) $(LDFLAGS)
android: $(SRC_FILES_ANDROID) android: $(SRC_FILES_ANDROID)
$(CC) -s $(CFLAGS) $(LUA_CFL) -o nfqws2 $(SRC_FILES_ANDROID) $(LIBS) $(LUA_LIB) $(LIBS_LINUX) $(LDFLAGS) $(LDFLAGS_ANDROID) $(CC) $(STRIPP) $(CFLAGS) $(LUA_CFL) -o nfqws2 $(SRC_FILES_ANDROID) $(LIBS) $(LUA_LIB) $(LIBS_LINUX) $(LDFLAGS) $(LDFLAGS_ANDROID)
bsd: $(SRC_FILES) bsd: $(SRC_FILES)
$(CC) -s $(CFLAGS) $(LUA_CFL) $(CFLAGS_BSD) -o dvtws2 $(SRC_FILES) $(LIBS) $(LUA_LIB) $(LIBS_BSD) $(LDFLAGS) $(CC) $(STRIPP) $(CFLAGS) $(LUA_CFL) $(CFLAGS_BSD) -o dvtws2 $(SRC_FILES) $(LIBS) $(LUA_LIB) $(LIBS_BSD) $(LDFLAGS)
cygwin64: cygwin64:
$(CC) -s $(CFLAGS) $(LUA_CFL) $(CFLAGS_CYGWIN) -o winws2 $(SRC_FILES) $(RES_CYGWIN64) $(LIBS) $(LUA_LIB) $(LIBS_CYGWIN) $(LIBS_CYGWIN64) $(LDFLAGS) $(CC) $(STRIPP) $(CFLAGS) $(LUA_CFL) $(CFLAGS_CYGWIN) $(CFLAGS_CYGWIN64) -o winws2 $(SRC_FILES) $(RES_CYGWIN64) $(LIBS) $(LUA_LIB) $(LIBS_CYGWIN) $(LIBS_CYGWIN64) $(LDFLAGS) $(LDFLAGS_CYGWIN)
cygwin32: cygwin32:
$(CC) -s $(CFLAGS) $(LUA_CFL) $(CFLAGS_CYGWIN) $(CFLAGS_CYGWIN32) -o winws2 $(SRC_FILES) $(RES_CYGWIN32) $(LIBS) $(LUA_LIB) $(LIBS_CYGWIN) $(LIBS_CYGWIN32) $(LDFLAGS) $(CC) $(STRIPP) $(CFLAGS) $(LUA_CFL) $(CFLAGS_CYGWIN) $(CFLAGS_CYGWIN32) -o winws2 $(SRC_FILES) $(RES_CYGWIN32) $(LIBS) $(LUA_LIB) $(LIBS_CYGWIN) $(LIBS_CYGWIN32) $(LDFLAGS) $(LDFLAGS_CYGWIN)
cygwin: cygwin64 cygwin: cygwin64
clean: clean:

View File

@@ -148,7 +148,7 @@ static void ConntrackApplyPos(t_ctrack *t, bool bReverse, const struct dissect *
if (scale != SCALE_NONE) direct->scale = scale; if (scale != SCALE_NONE) direct->scale = scale;
direct->mss = tcp_find_mss(dis->tcp); direct->mss = tcp_find_mss(dis->tcp);
} }
else if (direct->scale != SCALE_NONE) else
// apply scale only outside of the SYN stage // apply scale only outside of the SYN stage
direct->winsize_calc <<= direct->scale; direct->winsize_calc <<= direct->scale;
@@ -172,9 +172,6 @@ static void ConntrackApplyPos(t_ctrack *t, bool bReverse, const struct dissect *
static void ConntrackFeedPacket(t_ctrack *t, bool bReverse, const struct dissect *dis) static void ConntrackFeedPacket(t_ctrack *t, bool bReverse, const struct dissect *dis)
{ {
uint8_t scale;
uint16_t mss;
if (bReverse) if (bReverse)
{ {
t->pos.server.pcounter++; t->pos.server.pcounter++;
@@ -370,8 +367,8 @@ void ConntrackPoolDump(const t_conntrack *p)
t->track.pos.client.seq0, t->track.pos.client.seq_last - t->track.pos.client.seq0, t->track.pos.client.pos - t->track.pos.client.seq0, t->track.pos.client.seq0, t->track.pos.client.seq_last - t->track.pos.client.seq0, t->track.pos.client.pos - t->track.pos.client.seq0,
t->track.pos.server.seq0, t->track.pos.server.seq_last - t->track.pos.server.seq0, t->track.pos.server.pos - t->track.pos.server.seq0, t->track.pos.server.seq0, t->track.pos.server.seq_last - t->track.pos.server.seq0, t->track.pos.server.pos - t->track.pos.server.seq0,
t->track.pos.client.mss, t->track.pos.server.mss, t->track.pos.client.mss, t->track.pos.server.mss,
t->track.pos.client.winsize, t->track.pos.client.scale == SCALE_NONE ? -1 : t->track.pos.client.scale, t->track.pos.client.winsize, t->track.pos.client.scale,
t->track.pos.server.winsize, t->track.pos.server.scale == SCALE_NONE ? -1 : t->track.pos.server.scale); t->track.pos.server.winsize, t->track.pos.server.scale);
else else
printf("rseq=%u client.pos=%u rack=%u server.pos=%u", printf("rseq=%u client.pos=%u rack=%u server.pos=%u",
t->track.pos.client.seq_last, t->track.pos.client.pos, t->track.pos.client.seq_last, t->track.pos.client.pos,

View File

@@ -29,7 +29,7 @@ typedef struct
uint16_t winsize; // last seen window size uint16_t winsize; // last seen window size
uint16_t mss; uint16_t mss;
uint32_t winsize_calc; // calculated window size uint32_t winsize_calc; // calculated window size
uint8_t scale; // last seen window scale factor. SCALE_NONE if none uint8_t scale; // last seen window scale factor
bool rseq_over_2G; bool rseq_over_2G;
} t_ctrack_position; } t_ctrack_position;

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

View File

@@ -48,7 +48,7 @@ uint32_t net32_add(uint32_t netorder_value, uint32_t cpuorder_increment)
{ {
return htonl(ntohl(netorder_value)+cpuorder_increment); return htonl(ntohl(netorder_value)+cpuorder_increment);
} }
uint32_t net16_add(uint16_t netorder_value, uint16_t cpuorder_increment) uint16_t net16_add(uint16_t netorder_value, uint16_t cpuorder_increment)
{ {
return htons(ntohs(netorder_value)+cpuorder_increment); return htons(ntohs(netorder_value)+cpuorder_increment);
} }
@@ -229,7 +229,7 @@ uint16_t family_from_proto(uint8_t l3proto)
{ {
case IPPROTO_IP: return AF_INET; case IPPROTO_IP: return AF_INET;
case IPPROTO_IPV6: return AF_INET6; case IPPROTO_IPV6: return AF_INET6;
default: return -1; default: return AF_UNSPEC;
} }
} }
@@ -557,11 +557,15 @@ void proto_dissect_l3l4(const uint8_t *data, size_t len, struct dissect *dis, bo
dis->data_pkt = data; dis->data_pkt = data;
dis->len_pkt = len; dis->len_pkt = len;
uint16_t iplen;
if (proto_check_ipv4(data, len) && (no_payload_check || proto_check_ipv4_payload(data, len))) if (proto_check_ipv4(data, len) && (no_payload_check || proto_check_ipv4_payload(data, len)))
{ {
dis->ip = (const struct ip *) data; dis->ip = (const struct ip *) data;
dis->proto = dis->ip->ip_p; dis->proto = dis->ip->ip_p;
p = data; p = data;
iplen = ntohs(((struct ip*)data)->ip_len);
if (iplen<len) dis->len_pkt = len = iplen;
proto_skip_ipv4(&data, &len, &dis->frag, &dis->frag_off); proto_skip_ipv4(&data, &len, &dis->frag, &dis->frag_off);
dis->len_l3 = data-p; dis->len_l3 = data-p;
} }
@@ -569,6 +573,8 @@ void proto_dissect_l3l4(const uint8_t *data, size_t len, struct dissect *dis, bo
{ {
dis->ip6 = (const struct ip6_hdr *) data; dis->ip6 = (const struct ip6_hdr *) data;
p = data; p = data;
iplen = ntohs(((struct ip6_hdr*)data)->ip6_ctlun.ip6_un1.ip6_un1_plen) + sizeof(struct ip6_hdr);
if (iplen<len) dis->len_pkt = len = iplen;
proto_skip_ipv6(&data, &len, &dis->proto, &dis->frag, &dis->frag_off); proto_skip_ipv6(&data, &len, &dis->proto, &dis->frag, &dis->frag_off);
dis->len_l3 = data-p; dis->len_l3 = data-p;
} }
@@ -797,8 +803,8 @@ static BOOL RemoveTokenPrivs(void)
if (memcmp(&privs->Privileges[k].Luid, &luid_SeChangeNotifyPrivilege, sizeof(LUID))) if (memcmp(&privs->Privileges[k].Luid, &luid_SeChangeNotifyPrivilege, sizeof(LUID)))
privs->Privileges[k].Attributes = SE_PRIVILEGE_REMOVED; privs->Privileges[k].Attributes = SE_PRIVILEGE_REMOVED;
} }
bRes = AdjustTokenPrivileges(hToken, FALSE, privs, dwSize, NULL, NULL);
} }
bRes = AdjustTokenPrivileges(hToken, FALSE, privs, dwSize, NULL, NULL);
free(privs); free(privs);
} }
} }
@@ -2154,8 +2160,8 @@ static uint8_t *find_ie(uint8_t *buf, size_t len, uint8_t ie)
{ {
if (len<(2+buf[1])) break; if (len<(2+buf[1])) break;
if (buf[0]==ie) return buf; if (buf[0]==ie) return buf;
buf+=buf[1]+2;
len-=buf[1]+2; len-=buf[1]+2;
buf+=buf[1]+2;
} }
return NULL; return NULL;
} }
@@ -2238,6 +2244,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;

View File

@@ -94,7 +94,7 @@
// returns netorder value // returns netorder value
uint32_t net32_add(uint32_t netorder_value, uint32_t cpuorder_increment); uint32_t net32_add(uint32_t netorder_value, uint32_t cpuorder_increment);
uint32_t net16_add(uint16_t netorder_value, uint16_t cpuorder_increment); uint16_t net16_add(uint16_t netorder_value, uint16_t cpuorder_increment);
#define SCALE_NONE ((uint8_t)-1) #define SCALE_NONE ((uint8_t)-1)

View File

@@ -1648,9 +1648,12 @@ static const uint8_t *dns_extract_name(const uint8_t *a, const uint8_t *b, const
{ {
size_t nl, off; size_t nl, off;
const uint8_t *p; const uint8_t *p;
bool bptr = (*a & 0xC0)==0xC0; bool bptr;
uint8_t x,y; uint8_t x,y;
if (!name_size) return NULL;
bptr = (*a & 0xC0)==0xC0;
if (bptr) if (bptr)
{ {
if (a+1>=e) return NULL; if (a+1>=e) return NULL;
@@ -1665,66 +1668,115 @@ static const uint8_t *dns_extract_name(const uint8_t *a, const uint8_t *b, const
if (p>=e) return NULL; if (p>=e) return NULL;
for (nl=0; *p ;) for (nl=0; *p ;)
{ {
if (nl)
{
if (nl>=name_size) return NULL;
name[nl++] = '.';
}
// do not support mixed ptr+real // do not support mixed ptr+real
if ((*p & 0xC0) || (p+*p+1)>=e || (*p+1)>=(name_size-nl)) return NULL; if ((*p & 0xC0) || (p+*p+1)>=e || (*p+1)>=(name_size-nl)) return NULL;
if (nl) name[nl++] = '.';
for(y=*p++,x=0 ; x<y ; x++,p++) name[nl+x] = tolower(*p); for(y=*p++,x=0 ; x<y ; x++,p++) name[nl+x] = tolower(*p);
nl += y; nl += y;
} }
if (nl>=name_size) return NULL;
name[nl] = 0; name[nl] = 0;
return bptr ? a+2 : p+1; return bptr ? a+2 : p+1;
} }
static bool dns_skip_name(const uint8_t **a, size_t *len)
{
// 11 higher bits indicate pointer
// lazy skip name. mixed compressed/uncompressed names are supported
for(;;)
{
if (*len<2) return false;
if ((**a & 0xC0)==0xC0)
{
// pointer is the end
(*a)+=2; (*len)-=2;
break;
}
if (!**a)
{
// zero length is the end
(*a)++; (*len)--;
break;
}
if (*len<(**a+1)) return false;
*len-=**a+1;
*a+=**a+1;
}
return true;
}
static bool feed_dns_response(const uint8_t *a, size_t len) static bool feed_dns_response(const uint8_t *a, size_t len)
{ {
if (!params.cache_hostname) return true; if (!params.cache_hostname) return true;
// check of minimum header length and response flag // check of minimum header length and response flag
uint16_t k, off, dlen, qcount = a[4]<<8 | a[5], acount = a[6]<<8 | a[7]; uint16_t k, typ, off, dlen, qcount = a[4]<<8 | a[5], acount = a[6]<<8 | a[7];
char s_ip[INET6_ADDRSTRLEN]; char s_ip[INET6_ADDRSTRLEN];
const uint8_t *b = a, *p; const uint8_t *b = a, *p;
const uint8_t *e = b + len; const uint8_t *e = b + len;
size_t nl; size_t nl;
char name[256] = ""; char name[256] = "";
if (len<12 || !(a[2]&0x80)) return false; if (!qcount || len<12 || !(a[2]&0x80)) return false;
a+=12; len-=12; if (!acount)
for(k=0;k<qcount;k++)
{ {
DLOG("skipping DNS response without answer\n");
return false;
}
a+=12; len-=12;
for(k=0,*name = 0 ; k<qcount ; k++)
{
if (*name) return false; // we do not support multiple queries with names
// remember original query name // remember original query name
if (!(p = dns_extract_name(a, b, e, name, sizeof(name)))) return false; if (!(p = dns_extract_name(a, b, e, name, sizeof(name)))) return false;
len -= p-a; len -= p-a;
if ((len<4) || p[2] || p[3]!=1) return false;
typ = pntoh16(p);
// must be A or AAAA query. others are not interesting // must be A or AAAA query. others are not interesting
if ((len<4) || p[0] || p[1]!=1 && p[1]!=28 || p[2] || p[3]!=1) return false; if (typ!=1 && typ!=28)
{
DLOG("skipping DNS query type %u for '%s'\n", typ, name);
return false;
}
else
{
DLOG("DNS query type %u for '%s'\n", typ, name);
}
// skip type, class // skip type, class
a=p+4; len-=4; a=p+4; len-=4;
} }
if (!*name) return false; if (!*name) return false;
for(k=0;k<acount;k++) for(k=0;k<acount;k++)
{ {
// 11 higher bits indicate pointer if (!dns_skip_name(&a,&len)) return false;
if (len<12 || (*a & 0xC0)!=0xC0) return false; if (len<10) return false;
dlen = a[8]<<8 | a[9];
dlen = a[10]<<8 | a[11]; if (len<(dlen+10)) return false;
if (len<(dlen+12)) return false; if (a[2]==0 && a[3]==1) // IN class
if (a[4]==0 && a[5]==1 && a[2]==0) // IN class and higher byte of type = 0
{ {
switch(a[3]) typ = pntoh16(a);
switch(typ)
{ {
case 1: // A case 1: // A
if (dlen!=4) break; if (dlen!=4) break;
if (params.debug && inet_ntop(AF_INET, a+12, s_ip, sizeof(s_ip))) if (params.debug && inet_ntop(AF_INET, a+10, s_ip, sizeof(s_ip)))
DLOG("DNS response : %s\n", s_ip); DLOG("DNS response type %u : %s\n", typ, s_ip);
ipcache_put_hostname((struct in_addr *)(a+12), NULL, name, false); ipcache_put_hostname((struct in_addr *)(a+10), NULL, name, false);
break; break;
case 28: // AAAA case 28: // AAAA
if (dlen!=16) break; if (dlen!=16) break;
if (params.debug && inet_ntop(AF_INET6, a+12, s_ip, sizeof(s_ip))) if (params.debug && inet_ntop(AF_INET6, a+10, s_ip, sizeof(s_ip)))
DLOG("DNS response : %s\n", s_ip); DLOG("DNS response type %u : %s\n", typ, s_ip);
ipcache_put_hostname(NULL, (struct in6_addr *)(a+12), name, false); ipcache_put_hostname(NULL, (struct in6_addr *)(a+10), name, false);
break; break;
default:
DLOG("skipping DNS response type %u\n", typ);
} }
} }
len -= 12+dlen; a += 12+dlen; len -= 10+dlen; a += 10+dlen;
} }
return true; return true;
} }
@@ -1891,7 +1943,7 @@ rediscover_cancel:
ps.verdict = desync(ps.dp, fwmark, ifin, ifout, ps.bReverseFixed, ps.ctrack_replay, tpos, ps.l7payload, ps.l7proto, dis, ps.sdip4, ps.sdip6, ps.sdport, mod_pkt, len_mod_pkt, replay_piece, replay_piece_count, reasm_offset, NULL, 0, data_decrypt, len_decrypt); ps.verdict = desync(ps.dp, fwmark, ifin, ifout, ps.bReverseFixed, ps.ctrack_replay, tpos, ps.l7payload, ps.l7proto, dis, ps.sdip4, ps.sdip6, ps.sdport, mod_pkt, len_mod_pkt, replay_piece, replay_piece_count, reasm_offset, NULL, 0, data_decrypt, len_decrypt);
pass: pass:
return (!ps.bReverse && (ps.verdict & VERDICT_MASK) == VERDICT_DROP) ? ct_new_postnat_fix(ps.ctrack, dis, mod_pkt, len_mod_pkt) : ps.verdict; return (!ps.bReverseFixed && (ps.verdict & VERDICT_MASK) == VERDICT_DROP) ? ct_new_postnat_fix(ps.ctrack, dis, mod_pkt, len_mod_pkt) : ps.verdict;
} }
// conntrack is supported only for RELATED icmp // conntrack is supported only for RELATED icmp
@@ -1951,7 +2003,7 @@ static uint8_t dpi_desync_icmp_packet(
// invert direction. they are answering to this packet // invert direction. they are answering to this packet
bReverse = !bReverse; bReverse = !bReverse;
DLOG("found conntrack entry. inverted reverse=%u\n",bReverse); DLOG("found conntrack entry. inverted reverse=%u\n",bReverse);
if (ctrack->dp_search_complete) if (ctrack->dp_search_complete && ctrack->dp)
{ {
// RELATED icmp processed within base connection profile // RELATED icmp processed within base connection profile
dp = ctrack->dp; dp = ctrack->dp;

View File

@@ -180,7 +180,7 @@ void str_cidr4(char *s, size_t s_len, const struct cidr4 *cidr)
} }
void print_cidr4(const struct cidr4 *cidr) void print_cidr4(const struct cidr4 *cidr)
{ {
char s[19]; char s[INET_ADDRSTRLEN+4];
str_cidr4(s,sizeof(s),cidr); str_cidr4(s,sizeof(s),cidr);
printf("%s",s); printf("%s",s);
} }
@@ -193,7 +193,7 @@ void str_cidr6(char *s, size_t s_len, const struct cidr6 *cidr)
} }
void print_cidr6(const struct cidr6 *cidr) void print_cidr6(const struct cidr6 *cidr)
{ {
char s[INET_ADDRSTRLEN+4]; char s[INET6_ADDRSTRLEN+4];
str_cidr6(s,sizeof(s),cidr); str_cidr6(s,sizeof(s),cidr);
printf("%s",s); printf("%s",s);
} }

View File

@@ -50,7 +50,6 @@ void qsort_ssize_t(ssize_t *array, int ct)
qsort(array, ct, sizeof(*array), cmp_ssize_t); qsort(array, ct, sizeof(*array), cmp_ssize_t);
} }
int str_index(const char **strs, int count, const char *str) int str_index(const char **strs, int count, const char *str)
{ {
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)

View File

@@ -12,6 +12,9 @@
#include <fcntl.h> #include <fcntl.h>
#define UNARY_PLUS(v) (v>0 ? "+" : "") #define UNARY_PLUS(v) (v>0 ? "+" : "")
//#define MIN(v1,v2) ((v1)<(v2) ? (v1) : (v2))
//#define MAX(v1,v2) ((v1)<(v2) ? (v2) : (v1))
// this saves memory. sockaddr_storage is larger than required. it can be 128 bytes. sockaddr_in6 is 28 bytes. // this saves memory. sockaddr_storage is larger than required. it can be 128 bytes. sockaddr_in6 is 28 bytes.
typedef union typedef union

View File

@@ -8,8 +8,10 @@ static bool addpool(hostlist_pool **hostlist, char **s, const char *end, int *ct
{ {
char *p=*s; char *p=*s;
for (; p<end && (*p==' ' || *p=='\t') ; p++);
*s = p;
// comment line ? // comment line ?
if ( *p != '#' && *p != ';' && *p != '/' && *p != '\r' && *p != '\n') if (p<end && *p != '#' && *p != ';' && *p != '/' && *p != '\r' && *p != '\n')
{ {
// advance until eol lowering all chars // advance until eol lowering all chars
uint32_t flags = 0; uint32_t flags = 0;
@@ -64,18 +66,21 @@ bool AppendHostList(hostlist_pool **hostlist, const char *filename)
{ {
DLOG_CONDUP("zlib compression detected. uncompressed size : %zu\n", zsize); DLOG_CONDUP("zlib compression detected. uncompressed size : %zu\n", zsize);
p = zbuf; if (zbuf)
e = zbuf + zsize;
while(p<e)
{ {
if (!addpool(hostlist,&p,e,&ct)) p = zbuf;
e = zbuf + zsize;
while(p<e)
{ {
DLOG_ERR("Not enough memory to store host list : %s\n", filename); if (!addpool(hostlist,&p,e,&ct))
free(zbuf); {
return false; DLOG_ERR("Not enough memory to store host list : %s\n", filename);
free(zbuf);
return false;
}
} }
free(zbuf);
} }
free(zbuf);
} }
else else
{ {

View File

@@ -11,36 +11,42 @@ static bool addpool(ipset *ips, char **s, const char *end, int *ct)
struct cidr4 c4; struct cidr4 c4;
struct cidr6 c6; struct cidr6 c6;
for (p=*s; p<end && *p && *p!=' ' && *p!='\t' && *p!='\r' && *p != '\n'; p++); for (p=*s; p<end && (*p==' ' || *p=='\t') ; p++);
if (p<end)
// comment line
if (!(**s == '#' || **s == ';' || **s == '/' || **s == '\r' || **s == '\n' ))
{ {
l = p-*s; // comment line
if (l>=sizeof(cidr)) l=sizeof(cidr)-1; if (!(*p == '#' || *p == ';' || *p == '/' || *p == '\r' || *p == '\n' ))
memcpy(cidr,*s,l); {
cidr[l]=0; *s=p;
// advance to the token's end
for (; p<end && *p && *p!=' ' && *p!='\t' && *p!='\r' && *p != '\n'; p++);
if (parse_cidr4(cidr,&c4)) l = p-*s;
{ if (l>=sizeof(cidr)) l=sizeof(cidr)-1;
if (!ipset4AddCidr(&ips->ips4, &c4)) memcpy(cidr,*s,l);
cidr[l]=0;
if (parse_cidr4(cidr,&c4))
{ {
ipsetDestroy(ips); if (!ipset4AddCidr(&ips->ips4, &c4))
return false; {
ipsetDestroy(ips);
return false;
}
if (ct) (*ct)++;
} }
if (ct) (*ct)++; else if (parse_cidr6(cidr,&c6))
}
else if (parse_cidr6(cidr,&c6))
{
if (!ipset6AddCidr(&ips->ips6, &c6))
{ {
ipsetDestroy(ips); if (!ipset6AddCidr(&ips->ips6, &c6))
return false; {
ipsetDestroy(ips);
return false;
}
if (ct) (*ct)++;
} }
if (ct) (*ct)++; else
DLOG_ERR("bad ip or subnet : %s\n",cidr);
} }
else
DLOG_ERR("bad ip or subnet : %s\n",cidr);
} }
// skip remaining non-eol chars // skip remaining non-eol chars
@@ -81,18 +87,21 @@ static bool AppendIpset(ipset *ips, const char *filename)
{ {
DLOG_CONDUP("zlib compression detected. uncompressed size : %zu\n", zsize); DLOG_CONDUP("zlib compression detected. uncompressed size : %zu\n", zsize);
p = zbuf; if (zbuf)
e = zbuf + zsize;
while(p<e)
{ {
if (!addpool(ips,&p,e,&ct)) p = zbuf;
e = zbuf + zsize;
while(p<e)
{ {
DLOG_ERR("Not enough memory to store ipset : %s\n", filename); if (!addpool(ips,&p,e,&ct))
free(zbuf); {
return false; DLOG_ERR("Not enough memory to store ipset : %s\n", filename);
free(zbuf);
return false;
}
} }
free(zbuf);
} }
free(zbuf);
} }
else else
{ {
@@ -104,7 +113,7 @@ static bool AppendIpset(ipset *ips, const char *filename)
{ {
DLOG_CONDUP("loading plain text list\n"); DLOG_CONDUP("loading plain text list\n");
while (fgets(s, sizeof(s)-1, F)) while (fgets_safe(s, sizeof(s)-1, F))
{ {
p = s; p = s;
if (!addpool(ips,&p,p+strlen(p),&ct)) if (!addpool(ips,&p,p+strlen(p),&ct))

View File

@@ -1868,7 +1868,7 @@ static bool lua_reconstruct_ip6exthdr(lua_State *L, int idx, struct ip6_hdr *ip6
{ {
LUA_STACK_GUARD_ENTER(L) LUA_STACK_GUARD_ENTER(L)
// proto = last header type // proto = last header type
if (*len<sizeof(struct tcphdr)) return false; if (*len<sizeof(struct ip6_hdr)) return false;
uint8_t *last_proto = &ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt; uint8_t *last_proto = &ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt;
size_t filled = sizeof(struct ip6_hdr); size_t filled = sizeof(struct ip6_hdr);
@@ -1905,11 +1905,24 @@ static bool lua_reconstruct_ip6exthdr(lua_State *L, int idx, struct ip6_hdr *ip6
lua_getfield(L,-1, "data"); lua_getfield(L,-1, "data");
if (lua_type(L,-1)!=LUA_TSTRING) goto err; if (lua_type(L,-1)!=LUA_TSTRING) goto err;
if (!(p=(uint8_t*)lua_tolstring(L,-1,&l))) l=0; if (!(p=(uint8_t*)lua_tolstring(L,-1,&l))) l=0;
if (l<6 || (l+2)>left || (type==IPPROTO_AH ? (l>=1024 || ((l+2) & 3)) : (l>=2048 || ((l+2) & 7)))) goto err;
memcpy(data+2,p,l); if (l<6 || (l+2)>left) goto err;
l+=2; if (type==IPPROTO_AH)
{
if (l>=1024 || ((l+2) & 3)) goto err;
memcpy(data+2,p,l);
l+=2;
data[1] = (l>>2)-2;
}
else
{
if (l>=2048 || ((l+2) & 7)) goto err;
memcpy(data+2,p,l);
l+=2;
data[1] = (l>>3)-1;
}
data[0] = next; // may be overwritten later data[0] = next; // may be overwritten later
data[1] = (type==IPPROTO_AH) ? (l>>2)-2 : (l>>3)-1;
if (!preserve_next) *last_proto = type; if (!preserve_next) *last_proto = type;
last_proto = data; // first byte of header holds type last_proto = data; // first byte of header holds type
left -= l; data += l; filled += l; left -= l; data += l; filled += l;
@@ -2018,7 +2031,7 @@ bool lua_reconstruct_iphdr(lua_State *L, int idx, struct ip *ip, size_t *len)
LUA_STACK_GUARD_ENTER(L) LUA_STACK_GUARD_ENTER(L)
if (*len<sizeof(struct ip) || lua_type(L,-1)!=LUA_TTABLE) return false; if (*len<sizeof(struct ip) || lua_type(L,idx)!=LUA_TTABLE) return false;
ip->ip_v = IPVERSION; ip->ip_v = IPVERSION;
@@ -2188,7 +2201,7 @@ err:
} }
bool lua_reconstruct_tcphdr(lua_State *L, int idx, struct tcphdr *tcp, size_t *len) bool lua_reconstruct_tcphdr(lua_State *L, int idx, struct tcphdr *tcp, size_t *len)
{ {
if (*len<sizeof(struct tcphdr) || lua_type(L,-1)!=LUA_TTABLE) return false; if (*len<sizeof(struct tcphdr) || lua_type(L,idx)!=LUA_TTABLE) return false;
LUA_STACK_GUARD_ENTER(L) LUA_STACK_GUARD_ENTER(L)
@@ -2263,7 +2276,7 @@ static int luacall_reconstruct_tcphdr(lua_State *L)
bool lua_reconstruct_udphdr(lua_State *L, int idx, struct udphdr *udp) bool lua_reconstruct_udphdr(lua_State *L, int idx, struct udphdr *udp)
{ {
if (lua_type(L,-1)!=LUA_TTABLE) return false; if (lua_type(L,idx)!=LUA_TTABLE) return false;
LUA_STACK_GUARD_ENTER(L) LUA_STACK_GUARD_ENTER(L)
@@ -2307,7 +2320,7 @@ static int luacall_reconstruct_udphdr(lua_State *L)
bool lua_reconstruct_icmphdr(lua_State *L, int idx, struct icmp46 *icmp) bool lua_reconstruct_icmphdr(lua_State *L, int idx, struct icmp46 *icmp)
{ {
if (lua_type(L,-1)!=LUA_TTABLE) return false; if (lua_type(L,idx)!=LUA_TTABLE) return false;
LUA_STACK_GUARD_ENTER(L) LUA_STACK_GUARD_ENTER(L)
@@ -3337,7 +3350,6 @@ static int luacall_tls_mod(lua_State *L)
int argc=lua_gettop(L); int argc=lua_gettop(L);
size_t fake_tls_len; size_t fake_tls_len;
bool bRes;
const uint8_t *fake_tls = (uint8_t*)lua_reqlstring(L,1,&fake_tls_len); const uint8_t *fake_tls = (uint8_t*)lua_reqlstring(L,1,&fake_tls_len);
const char *modlist = lua_reqstring(L,2); const char *modlist = lua_reqstring(L,2);
@@ -3357,8 +3369,10 @@ static int luacall_tls_mod(lua_State *L)
uint8_t *newtls = lua_newuserdata(L, maxlen); uint8_t *newtls = lua_newuserdata(L, maxlen);
memcpy(newtls, fake_tls, newlen); memcpy(newtls, fake_tls, newlen);
bRes = TLSMod(&mod, payload, payload_len, newtls, &newlen, maxlen); if (TLSMod(&mod, payload, payload_len, newtls, &newlen, maxlen))
lua_pushlstring(L,(char*)newtls,newlen); lua_pushlstring(L,(char*)newtls,newlen);
else
lua_pushnil(L);
lua_remove(L,-2); lua_remove(L,-2);
} }
@@ -3366,11 +3380,9 @@ static int luacall_tls_mod(lua_State *L)
{ {
// no mod. push it back // no mod. push it back
lua_pushlstring(L,(char*)fake_tls,fake_tls_len); lua_pushlstring(L,(char*)fake_tls,fake_tls_len);
bRes = true;
} }
lua_pushboolean(L, bRes);
LUA_STACK_GUARD_RETURN(L,2) LUA_STACK_GUARD_RETURN(L,1)
} }
struct userdata_zs struct userdata_zs
@@ -3714,7 +3726,7 @@ static void lua_xtime(lua_State *L, struct tm *(*timefunc)(const time_t *,struct
lua_pushf_int(L,"isdst", t.tm_isdst); lua_pushf_int(L,"isdst", t.tm_isdst);
lua_pushf_str(L,"zone", t.tm_zone); lua_pushf_str(L,"zone", t.tm_zone);
char s[24]; char s[40];
snprintf(s,sizeof(s),"%02d.%02d.%04d %02d:%02d:%02d", t.tm_mday, t.tm_mon + 1, t.tm_year + 1900, t.tm_hour, t.tm_min, t.tm_sec); snprintf(s,sizeof(s),"%02d.%02d.%04d %02d:%02d:%02d", t.tm_mday, t.tm_mon + 1, t.tm_year + 1900, t.tm_hour, t.tm_min, t.tm_sec);
lua_pushf_str(L,"str", s); lua_pushf_str(L,"str", s);
} }

View File

@@ -43,6 +43,7 @@
#endif #endif
#ifdef __linux__ #ifdef __linux__
#include <sys/ioctl.h>
#include <libnetfilter_queue/libnetfilter_queue.h> #include <libnetfilter_queue/libnetfilter_queue.h>
#define NF_DROP 0 #define NF_DROP 0
#define NF_ACCEPT 1 #define NF_ACCEPT 1
@@ -240,6 +241,13 @@ static int write_pidfile(FILE **Fpid)
#ifdef __linux__ #ifdef __linux__
struct nfq_cb_data
{
uint8_t *mod;
int sock;
};
// cookie must point to mod buffer with size RECONSTRUCT_MAX_SIZE // cookie must point to mod buffer with size RECONSTRUCT_MAX_SIZE
static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *cookie) static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *cookie)
{ {
@@ -247,27 +255,32 @@ static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_da
size_t len; size_t len;
struct nfqnl_msg_packet_hdr *ph; struct nfqnl_msg_packet_hdr *ph;
uint8_t *data; uint8_t *data;
uint32_t ifidx_out, ifidx_in;
char ifout[IFNAMSIZ], ifin[IFNAMSIZ];
size_t modlen; size_t modlen;
uint8_t *mod = (uint8_t*)cookie; struct nfq_cb_data *cbdata = (struct nfq_cb_data*)cookie;
uint32_t mark; uint32_t mark;
struct ifreq ifr_in, ifr_out;
ph = nfq_get_msg_packet_hdr(nfa); if (!(ph = nfq_get_msg_packet_hdr(nfa))) return 0; // should not happen
id = ph ? ntohl(ph->packet_id) : 0; id = ntohl(ph->packet_id);
mark = nfq_get_nfmark(nfa); mark = nfq_get_nfmark(nfa);
ilen = nfq_get_payload(nfa, &data); ilen = nfq_get_payload(nfa, &data);
ifidx_out = nfq_get_outdev(nfa); // if_indextoname creates socket, calls ioctl, closes socket
*ifout = 0; // code below prevents socket() and close() syscalls on every packet
if (ifidx_out) if_indextoname(ifidx_out, ifout); // this saves CPU 5-10 times
ifidx_in = nfq_get_indev(nfa); *ifr_out.ifr_name = 0;
*ifin = 0; ifr_out.ifr_ifindex = nfq_get_outdev(nfa);
if (ifidx_in) if_indextoname(ifidx_in, ifin); if (ifr_out.ifr_ifindex && ioctl(cbdata->sock, SIOCGIFNAME, &ifr_out)<0)
DLOG_PERROR("ioctl(SIOCGIFNAME)");
DLOG("\npacket: id=%d len=%d mark=%08X ifin=%s(%u) ifout=%s(%u)\n", id, ilen, mark, ifin, ifidx_in, ifout, ifidx_out); *ifr_in.ifr_name = 0;
ifr_in.ifr_ifindex = nfq_get_indev(nfa);
if (ifr_in.ifr_ifindex && ioctl(cbdata->sock, SIOCGIFNAME, &ifr_in)<0)
DLOG_PERROR("ioctl(SIOCGIFNAME)");
DLOG("\npacket: id=%d len=%d mark=%08X ifin=%s(%u) ifout=%s(%u)\n", id, ilen, mark, ifr_in.ifr_name, ifr_in.ifr_ifindex, ifr_out.ifr_name, ifr_out.ifr_ifindex);
if (ilen >= 0) if (ilen >= 0)
{ {
@@ -277,12 +290,12 @@ static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_da
// to support increased sizes use separate mod buffer // to support increased sizes use separate mod buffer
// this is not a problem because only LUA code can trigger VERDICT_MODIFY (and postnat workaround too, once a connection if first packet is dropped) // this is not a problem because only LUA code can trigger VERDICT_MODIFY (and postnat workaround too, once a connection if first packet is dropped)
// in case of VERIDCT_MODIFY packet is always reconstructed from dissect, so no difference where to save the data => no performance loss // in case of VERIDCT_MODIFY packet is always reconstructed from dissect, so no difference where to save the data => no performance loss
uint8_t verdict = processPacketData(&mark, ifin, ifout, data, len, mod, &modlen); uint8_t verdict = processPacketData(&mark, ifr_in.ifr_name, ifr_out.ifr_name, data, len, cbdata->mod, &modlen);
switch (verdict & VERDICT_MASK) switch (verdict & VERDICT_MASK)
{ {
case VERDICT_MODIFY: case VERDICT_MODIFY:
DLOG("packet: id=%d pass modified. len %zu => %zu\n", id, len, modlen); DLOG("packet: id=%d pass modified. len %zu => %zu\n", id, len, modlen);
return nfq_set_verdict2(qh, id, NF_ACCEPT, mark, (uint32_t)modlen, mod); return nfq_set_verdict2(qh, id, NF_ACCEPT, mark, (uint32_t)modlen, cbdata->mod);
case VERDICT_DROP: case VERDICT_DROP:
DLOG("packet: id=%d drop\n", id); DLOG("packet: id=%d drop\n", id);
return nfq_set_verdict2(qh, id, NF_DROP, mark, 0, NULL); return nfq_set_verdict2(qh, id, NF_DROP, mark, 0, NULL);
@@ -306,7 +319,7 @@ static void nfq_deinit(struct nfq_handle **h, struct nfq_q_handle **qh)
*h = NULL; *h = NULL;
} }
} }
static bool nfq_init(struct nfq_handle **h, struct nfq_q_handle **qh, uint8_t *mod_buffer) static bool nfq_init(struct nfq_handle **h, struct nfq_q_handle **qh, struct nfq_cb_data *cbdata)
{ {
nfq_deinit(h, qh); nfq_deinit(h, qh);
@@ -343,7 +356,7 @@ static bool nfq_init(struct nfq_handle **h, struct nfq_q_handle **qh, uint8_t *m
} }
DLOG_CONDUP("binding this socket to queue '%u'\n", params.qnum); DLOG_CONDUP("binding this socket to queue '%u'\n", params.qnum);
*qh = nfq_create_queue(*h, params.qnum, &nfq_cb, mod_buffer); *qh = nfq_create_queue(*h, params.qnum, &nfq_cb, cbdata);
if (!*qh) { if (!*qh) {
DLOG_PERROR("nfq_create_queue()"); DLOG_PERROR("nfq_create_queue()");
goto exiterr; goto exiterr;
@@ -365,6 +378,12 @@ static bool nfq_init(struct nfq_handle **h, struct nfq_q_handle **qh, uint8_t *m
// dot not fail. not supported in old linuxes <3.6 // dot not fail. not supported in old linuxes <3.6
} }
unsigned int rcvbuf = nfnl_rcvbufsiz(nfq_nfnlh(*h), Q_RCVBUF) / 2;
if (rcvbuf==Q_RCVBUF)
DLOG("set receive buffer size to %u\n", rcvbuf);
else
DLOG_CONDUP("could not set receive buffer size to %u. real size is %u\n", Q_RCVBUF, rcvbuf);
int yes = 1, fd = nfq_fd(*h); int yes = 1, fd = nfq_fd(*h);
#if defined SOL_NETLINK && defined NETLINK_NO_ENOBUFS #if defined SOL_NETLINK && defined NETLINK_NO_ENOBUFS
@@ -387,6 +406,8 @@ static void notify_ready(void)
#endif #endif
} }
// extra space for netlink headers
#define NFQ_MAX_RECV_SIZE (RECONSTRUCT_MAX_SIZE+4096)
static int nfq_main(void) static int nfq_main(void)
{ {
struct nfq_handle *h = NULL; struct nfq_handle *h = NULL;
@@ -395,6 +416,7 @@ static int nfq_main(void)
ssize_t rd; ssize_t rd;
FILE *Fpid = NULL; FILE *Fpid = NULL;
uint8_t *buf=NULL, *mod=NULL; uint8_t *buf=NULL, *mod=NULL;
struct nfq_cb_data cbdata = { .sock = -1, .mod = NULL };
if (*params.pidfile && !(Fpid = fopen(params.pidfile, "w"))) if (*params.pidfile && !(Fpid = fopen(params.pidfile, "w")))
{ {
@@ -436,13 +458,19 @@ static int nfq_main(void)
goto exok; goto exok;
} }
if (!(buf = malloc(RECONSTRUCT_MAX_SIZE)) || !(mod = malloc(RECONSTRUCT_MAX_SIZE))) if (!(buf = malloc(NFQ_MAX_RECV_SIZE)) || !(cbdata.mod = malloc(RECONSTRUCT_MAX_SIZE)))
{ {
DLOG_ERR("out of memory\n"); DLOG_ERR("out of memory\n");
goto err; goto err;
} }
if (!nfq_init(&h, &qh, mod)) if ((cbdata.sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
DLOG_PERROR("socket");
goto err;
}
if (!nfq_init(&h, &qh, &cbdata))
goto err; goto err;
#ifdef HAS_FILTER_SSID #ifdef HAS_FILTER_SSID
@@ -466,7 +494,7 @@ static int nfq_main(void)
do do
{ {
if (bQuit) goto quit; if (bQuit) goto quit;
while ((rd = recv(fd, buf, RECONSTRUCT_MAX_SIZE, 0)) >= 0) while ((rd = recv(fd, buf, NFQ_MAX_RECV_SIZE, 0)) >= 0)
{ {
if (!rd) if (!rd)
{ {
@@ -481,7 +509,7 @@ static int nfq_main(void)
DLOG_ERR("cannot get wlan info\n"); DLOG_ERR("cannot get wlan info\n");
#endif #endif
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));
if (bQuit) goto quit; if (bQuit) goto quit;
} }
if (errno==EINTR) if (errno==EINTR)
@@ -493,10 +521,18 @@ static int nfq_main(void)
// do not fail on ENOBUFS // do not fail on ENOBUFS
} while (e == ENOBUFS); } while (e == ENOBUFS);
err:
res=1;
goto ex;
quit:
DLOG_CONDUP("quit requested\n");
exok: exok:
res=0; res=0;
ex: ex:
free(mod); if (Fpid) fclose(Fpid);
if (cbdata.sock>=0) close(cbdata.sock);
free(cbdata.mod);
free(buf); free(buf);
nfq_deinit(&h, &qh); nfq_deinit(&h, &qh);
lua_shutdown(); lua_shutdown();
@@ -505,13 +541,6 @@ ex:
#endif #endif
rawsend_cleanup(); rawsend_cleanup();
return res; return res;
err:
if (Fpid) fclose(Fpid);
res=1;
goto ex;
quit:
DLOG_CONDUP("quit requested\n");
goto exok;
} }
#elif defined(BSD) #elif defined(BSD)
@@ -641,6 +670,7 @@ static int dvt_main(void)
if (rd < 0) if (rd < 0)
{ {
DLOG_PERROR("recvfrom"); DLOG_PERROR("recvfrom");
if (errno==ENOBUFS) continue;
goto exiterr; goto exiterr;
} }
else if (rd > 0) else if (rd > 0)
@@ -1255,7 +1285,7 @@ struct func_list *parse_lua_call(char *opt, struct func_list_head *flist)
struct func_list *f = NULL; struct func_list *f = NULL;
if (!(name = item_name(&opt))) if (!(name = item_name(&opt)))
return false; return NULL;
if (!is_identifier(name) || !(f=funclist_add_tail(flist,name))) if (!is_identifier(name) || !(f=funclist_add_tail(flist,name)))
goto err; goto err;
@@ -2508,7 +2538,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");
@@ -2517,7 +2547,7 @@ int main(int argc, char **argv)
dp->b_hostlist_auto_fail_threshold = true; dp->b_hostlist_auto_fail_threshold = true;
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");
@@ -2526,7 +2556,7 @@ int main(int argc, char **argv)
dp->b_hostlist_auto_fail_time = true; dp->b_hostlist_auto_fail_time = true;
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");

View File

@@ -116,7 +116,7 @@ static char log_buf[4096];
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);
} }
static int DLOG_FILENAME(const char *filename, const char *format, ...) static int DLOG_FILENAME(const char *filename, const char *format, ...)
@@ -130,7 +130,7 @@ static int DLOG_FILENAME(const char *filename, const char *format, ...)
} }
static void file_log_function(int priority, const char *line) static void file_log_function(int priority, const char *line)
{ {
DLOG_FILENAME(params.debug_logfile,"%s",log_buf); DLOG_FILENAME(params.debug_logfile,"%s",line);
} }
#ifdef __ANDROID__ #ifdef __ANDROID__
@@ -405,7 +405,7 @@ static struct desync_profile_list *desync_profile_entry_alloc()
struct desync_profile_list *dp_list_add(struct desync_profile_list_head *head) struct desync_profile_list *dp_list_add(struct desync_profile_list_head *head)
{ {
struct desync_profile_list *entry = desync_profile_entry_alloc(); struct desync_profile_list *entry = desync_profile_entry_alloc();
if (!entry) return false; if (!entry) return NULL;
struct desync_profile_list *tail, *item; struct desync_profile_list *tail, *item;
LIST_TAIL(head, tail, item); LIST_TAIL(head, tail, item);

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 4096 // in packets
#define Q_RCVBUF (1024*1024) // in bytes
#define HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT 3 #define HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT 3
#define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60 #define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60

View File

@@ -493,7 +493,6 @@ void kavl_bit_destroy(struct kavl_bit_elem **hdr)
if (!e) break; if (!e) break;
kavl_bit_destroy_elem(e); kavl_bit_destroy_elem(e);
} }
free(*hdr);
} }
struct kavl_bit_elem *kavl_bit_add(struct kavl_bit_elem **hdr, void *data, unsigned int bitlen, size_t struct_size) struct kavl_bit_elem *kavl_bit_add(struct kavl_bit_elem **hdr, void *data, unsigned int bitlen, size_t struct_size)
{ {

View File

@@ -331,7 +331,7 @@ bool IsHttpReply(const uint8_t *data, size_t len)
data[10]>='0' && data[10]<='9' && data[10]>='0' && data[10]<='9' &&
data[11]>='0' && data[11]<='9'; data[11]>='0' && data[11]<='9';
} }
int HttpReplyCode(const uint8_t *data, size_t len) int HttpReplyCode(const uint8_t *data)
{ {
return (data[9]-'0')*100 + (data[10]-'0')*10 + (data[11]-'0'); return (data[9]-'0')*100 + (data[10]-'0')*10 + (data[11]-'0');
} }
@@ -370,7 +370,7 @@ bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, const char *
if (!host || !*host || !IsHttpReply(data, len)) return false; if (!host || !*host || !IsHttpReply(data, len)) return false;
code = HttpReplyCode(data,len); code = HttpReplyCode(data);
if ((code!=302 && code!=307) || !HttpExtractHeader(data,len,"\nLocation:",loc,sizeof(loc))) return false; if ((code!=302 && code!=307) || !HttpExtractHeader(data,len,"\nLocation:",loc,sizeof(loc))) return false;
@@ -565,7 +565,7 @@ bool TLSFindExtLenOffsetInHandshake(const uint8_t *data, size_t len, size_t *off
} }
bool TLSFindExtLen(const uint8_t *data, size_t len, size_t *off) bool TLSFindExtLen(const uint8_t *data, size_t len, size_t *off)
{ {
if (!TLSFindExtLenOffsetInHandshake(data+5,len-5,off)) if (len<5 || !TLSFindExtLenOffsetInHandshake(data+5,len-5,off))
return false; return false;
*off+=5; *off+=5;
return true; return true;
@@ -649,9 +649,11 @@ bool TLSAdvanceToHostInSNI(const uint8_t **ext, size_t *elen, size_t *slen)
// u8 data+2 - server name type. 0=host_name // u8 data+2 - server name type. 0=host_name
// u16 data+3 - server name length // u16 data+3 - server name length
if (*elen < 5 || (*ext)[2] != 0) return false; if (*elen < 5 || (*ext)[2] != 0) return false;
uint16_t nll = pntoh16(*ext);
*slen = pntoh16(*ext + 3); *slen = pntoh16(*ext + 3);
if (nll<(*slen+3) || *slen > *elen-5) return false;
*ext += 5; *elen -= 5; *ext += 5; *elen -= 5;
return *slen <= *elen; return true;
} }
static bool TLSExtractHostFromExt(const uint8_t *ext, size_t elen, char *host, size_t len_host) static bool TLSExtractHostFromExt(const uint8_t *ext, size_t elen, char *host, size_t len_host)
{ {
@@ -1252,6 +1254,13 @@ static int cmp_range64(const void * a, const void * b)
{ {
return (((struct range64*)a)->offset < ((struct range64*)b)->offset) ? -1 : (((struct range64*)a)->offset > ((struct range64*)b)->offset) ? 1 : 0; return (((struct range64*)a)->offset < ((struct range64*)b)->offset) ? -1 : (((struct range64*)a)->offset > ((struct range64*)b)->offset) ? 1 : 0;
} }
/*
static bool intersected_u64(uint64_t l1, uint64_t r1, uint64_t l2, uint64_t r2)
{
return l1 <= r2 && l2 <= r1;
}
*/
bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,size_t *defrag_len, bool *bFull) bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,size_t *defrag_len, bool *bFull)
{ {
// Crypto frame can be split into multiple chunks // Crypto frame can be split into multiple chunks
@@ -1265,7 +1274,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)
{ {
@@ -1287,24 +1296,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
@@ -1313,21 +1352,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;
@@ -1350,6 +1375,8 @@ bool IsQUICInitial(const uint8_t *data, size_t len)
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];
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];
@@ -1445,7 +1472,7 @@ bool IsStunMessage(const uint8_t *data, size_t len)
(data[0]&0xC0)==0 && // 2 most significant bits must be zeroes (data[0]&0xC0)==0 && // 2 most significant bits must be zeroes
(data[3]&3)==0 && // length must be a multiple of 4 (data[3]&3)==0 && // length must be a multiple of 4
pntoh32(data+4)==0x2112A442 && // magic cookie pntoh32(data+4)==0x2112A442 && // magic cookie
pntoh16(data+2)==(len-20); pntoh16(data+2)<=(len-20);
} }
#if defined(__GNUC__) && !defined(__llvm__) #if defined(__GNUC__) && !defined(__llvm__)
__attribute__((optimize ("no-strict-aliasing"))) __attribute__((optimize ("no-strict-aliasing")))
@@ -1460,7 +1487,7 @@ bool IsMTProto(const uint8_t *data, size_t len)
return !memcmp(decrypt+56,"\xEF\xEF\xEF\xEF",4); return !memcmp(decrypt+56,"\xEF\xEF\xEF\xEF",4);
*/ */
// this way requires only one AES instead of 4 // this way requires only one AES instead of 4
uint8_t decrypt[16] __attribute__((aligned)), iv[16]; uint8_t decrypt[16] __attribute__((aligned(16))), iv[16] __attribute__((aligned(16)));
aes_context ctx; aes_context ctx;
memcpy(iv, data+40, 16); memcpy(iv, data+40, 16);

View File

@@ -104,7 +104,7 @@ bool HttpExtractHeader(const uint8_t *data, size_t len, const char *header, char
bool HttpExtractHost(const uint8_t *data, size_t len, char *host, size_t len_host); bool HttpExtractHost(const uint8_t *data, size_t len, char *host, size_t len_host);
bool IsHttpReply(const uint8_t *data, size_t len); bool IsHttpReply(const uint8_t *data, size_t len);
// must be pre-checked by IsHttpReply // must be pre-checked by IsHttpReply
int HttpReplyCode(const uint8_t *data, size_t len); int HttpReplyCode(const uint8_t *data);
// must be pre-checked by IsHttpReply // must be pre-checked by IsHttpReply
bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, const char *host); bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, const char *host);

View File

@@ -95,6 +95,10 @@ bool dropcaps(void);
# define ARCH_NR AUDIT_ARCH_LOONGARCH64 # 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"

View File

@@ -28,12 +28,6 @@ bool service_run(int argc, char *argv[])
return StartServiceCtrlDispatcherA(ServiceTable); return StartServiceCtrlDispatcherA(ServiceTable);
} }
static void service_set_status(DWORD state)
{
ServiceStatus.dwCurrentState = state;
SetServiceStatus(hStatus, &ServiceStatus);
}
// Control handler function // Control handler function
void service_controlhandler(DWORD request) void service_controlhandler(DWORD request)
{ {

View File

@@ -4,6 +4,6 @@
#include <stdbool.h> #include <stdbool.h>
bool service_run(); bool service_run(int argc, char *argv[]);
#endif #endif

Binary file not shown.

Binary file not shown.