mirror of
https://github.com/bol-van/zapret.git
synced 2025-04-19 05:22:58 +03:00
Compare commits
292 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
b996abd5ce | ||
|
12461de3b0 | ||
|
7dab497b57 | ||
|
41dbba1c4c | ||
|
d19f6c19a4 | ||
|
b12b1a5a17 | ||
|
8022e2576d | ||
|
f4ea264ba9 | ||
|
061acb27e4 | ||
|
8eb830d304 | ||
|
2fb93c6add | ||
|
ad5c246629 | ||
|
58e73d0331 | ||
|
9ebeff621a | ||
|
69df271a16 | ||
|
e285b2401d | ||
|
6e1e7e43bc | ||
|
d04419a60c | ||
|
fc1bf47e82 | ||
|
929df3f094 | ||
|
7272b243cb | ||
|
72d48d957a | ||
|
f4069d484a | ||
|
1c82b0a6af | ||
|
c08e69aa65 | ||
|
8097f08020 | ||
|
4cae291e6f | ||
|
82ad5508dc | ||
|
fa8ddcfc79 | ||
|
b560e32e18 | ||
|
67e1aee8a8 | ||
|
1d8385a9b4 | ||
|
340dec62a7 | ||
|
db4585c02f | ||
|
e792ca67ef | ||
|
e5e53db6b8 | ||
|
e14ee9d1fe | ||
|
360506ba4e | ||
|
aa769e05c6 | ||
|
6b0bc7a96b | ||
|
93bdfdb6be | ||
|
6d95eada2b | ||
|
e452ee8688 | ||
|
6e746f94cd | ||
|
9fd61e5d38 | ||
|
0c0fba4461 | ||
|
056e4c588a | ||
|
4b288643ac | ||
|
cbdee74e5f | ||
|
743eb5a4a2 | ||
|
4e8e3a9ed9 | ||
|
b9b91a0e68 | ||
|
9de7b66eef | ||
|
a2ffa3455d | ||
|
60b97dbed0 | ||
|
e56e4f5f35 | ||
|
5305ea83c8 | ||
|
14b3dd459b | ||
|
66fda2c33d | ||
|
77df43b9cb | ||
|
85f2b37c88 | ||
|
e2d600fcc6 | ||
|
37eda0ad98 | ||
|
770be21e1c | ||
|
1b880d42f9 | ||
|
6387315c0b | ||
|
3d4b395bfe | ||
|
55950ed7d0 | ||
|
f2b0341484 | ||
|
b2d89c5d22 | ||
|
778b611f86 | ||
|
ffaf91c251 | ||
|
326b42fafd | ||
|
94d4238af2 | ||
|
15e22fa1bd | ||
|
bd8decddc5 | ||
|
2db1ebafe3 | ||
|
33bcf6f7b4 | ||
|
f037f1acb2 | ||
|
cdd9b32b27 | ||
|
7934125c09 | ||
|
6493d55977 | ||
|
cafbb17e70 | ||
|
9ac73f7d2f | ||
|
08a6e8e069 | ||
|
644a934099 | ||
|
0eec445af0 | ||
|
b8acc1b979 | ||
|
123eb057ae | ||
|
56d06456fb | ||
|
a6efe05aa6 | ||
|
a1d29b0c3a | ||
|
756603338b | ||
|
8b73e2ea8e | ||
|
2a0e952153 | ||
|
1065202349 | ||
|
307d38f6af | ||
|
8ac4fc0af5 | ||
|
af89d03118 | ||
|
d89daaaeac | ||
|
f62b289cb5 | ||
|
5f9fa28251 | ||
|
bd67b41f32 | ||
|
00619c8dab | ||
|
58e26c3e9d | ||
|
eddbc3c3e0 | ||
|
2cc73de15c | ||
|
9762f2d22b | ||
|
8c9aa188c3 | ||
|
2f151c0943 | ||
|
9498456c4a | ||
|
860607bce2 | ||
|
94f59511f0 | ||
|
b07ce8d8ca | ||
|
6fc4e75d89 | ||
|
fb894a8e2c | ||
|
86352430d4 | ||
|
e5f20d05f6 | ||
|
b610f08a9c | ||
|
8bbd2d97d5 | ||
|
972f665d88 | ||
|
a9a497fa77 | ||
|
14a170c9a3 | ||
|
d4080b6c6f | ||
|
20f1fb2cfd | ||
|
35c3216287 | ||
|
628f629c49 | ||
|
33d3059dc8 | ||
|
f5cf7917fb | ||
|
b39508de7f | ||
|
c69a92f901 | ||
|
aba1fdeb04 | ||
|
02c76a4fb6 | ||
|
2ff6ec03aa | ||
|
80a0b38295 | ||
|
e0e935c2ae | ||
|
31cf106728 | ||
|
502e34a96d | ||
|
29ab747e5b | ||
|
b897ec5d9a | ||
|
440878cb9f | ||
|
1935473bd1 | ||
|
de6cadf8e4 | ||
|
d509497bb8 | ||
|
d7949f70b1 | ||
|
0912b7d104 | ||
|
29ff997a3f | ||
|
f21bd0c63c | ||
|
41693b1008 | ||
|
d000345043 | ||
|
f986da9ae2 | ||
|
c6e729b237 | ||
|
12a800db97 | ||
|
5e84656707 | ||
|
e87965cd2f | ||
|
4585cc4656 | ||
|
c0a08d3353 | ||
|
77474c9f76 | ||
|
15b2ee2d82 | ||
|
709279d6cf | ||
|
35d676406c | ||
|
9aff90b466 | ||
|
bc463930aa | ||
|
6fe9471077 | ||
|
884213f7ac | ||
|
80bf409615 | ||
|
3fe46ffb82 | ||
|
42c52014ee | ||
|
8aabc8b743 | ||
|
5df9b5d109 | ||
|
50616896c8 | ||
|
eb1cf7c15a | ||
|
b878c313f8 | ||
|
869e2cd8f9 | ||
|
8a996b415e | ||
|
62d2de904b | ||
|
a02be13dd1 | ||
|
c6058a4ea9 | ||
|
27ffe77243 | ||
|
3eb969cdaf | ||
|
73040bb156 | ||
|
c2bda9388f | ||
|
6cd0de7a0b | ||
|
85d319568c | ||
|
b3fd5c5dc1 | ||
|
202b7224fb | ||
|
647ee11917 | ||
|
63fbf2857c | ||
|
9c8636081c | ||
|
578d6d6db8 | ||
|
9ab9aef32b | ||
|
d4a72df111 | ||
|
ead91ae4f7 | ||
|
49385b6e57 | ||
|
499f9824ab | ||
|
2be5f1221a | ||
|
fef64e8849 | ||
|
675a8e52b6 | ||
|
d9a24b4105 | ||
|
594e613fcb | ||
|
7b7a6dd154 | ||
|
dcf78a76e5 | ||
|
fc42f6e20e | ||
|
45b93f3a45 | ||
|
1476cd2149 | ||
|
4ec6e5fa9f | ||
|
9d8398628c | ||
|
fe98c9d972 | ||
|
720c2fad86 | ||
|
7b057491af | ||
|
8e7b694076 | ||
|
e8395eea56 | ||
|
6e619eba1a | ||
|
f8bd218e67 | ||
|
207a6faf33 | ||
|
991e3534a6 | ||
|
ebb22dfa3f | ||
|
9bd65e0c1d | ||
|
5b337b6015 | ||
|
4189803693 | ||
|
1175b171ba | ||
|
bea643c967 | ||
|
addc813956 | ||
|
0f1721d2c4 | ||
|
abdc8d9449 | ||
|
9e9136cffd | ||
|
c802069a11 | ||
|
4e5caf4087 | ||
|
de63ee7321 | ||
|
d6688b935d | ||
|
21e08ca55e | ||
|
c4f53549b1 | ||
|
08645997f8 | ||
|
e42a545ebc | ||
|
8324c04a41 | ||
|
166847ba92 | ||
|
1904f01cf4 | ||
|
4ae1ad053d | ||
|
7d9946b007 | ||
|
86462f4cee | ||
|
669182c133 | ||
|
f81bb51f4a | ||
|
d4ff423add | ||
|
b14ff9b647 | ||
|
277c5f9e00 | ||
|
f016e5a4dc | ||
|
fc3912b4fe | ||
|
c01a764e1f | ||
|
4ecb40e03b | ||
|
be9c300cb3 | ||
|
839c720f60 | ||
|
127bec2f14 | ||
|
15879c82f6 | ||
|
9d188840c1 | ||
|
35a28f4efe | ||
|
78ea379e0f | ||
|
007cbe600b | ||
|
d1a8e276b5 | ||
|
eb2f5b5f45 | ||
|
a623cef95d | ||
|
f00b45a28e | ||
|
422faaa29c | ||
|
16a9e3f9c9 | ||
|
7c5869bc29 | ||
|
feb3dd4d73 | ||
|
b4204ca2ba | ||
|
89a67e6952 | ||
|
34199b151c | ||
|
c6962f575e | ||
|
9c8662b25e | ||
|
fedb62df66 | ||
|
44c19c1743 | ||
|
56aa481226 | ||
|
9184317549 | ||
|
a3048ae120 | ||
|
fc44d74f2b | ||
|
1779cfad30 | ||
|
4856be4ef1 | ||
|
033043bdc0 | ||
|
46284938ce | ||
|
09378553b9 | ||
|
6b85884cdf | ||
|
1b14a8210c | ||
|
182fe850db | ||
|
62b081e9fb | ||
|
e3e7449d74 | ||
|
669f1978a3 | ||
|
57c4b1a2b2 | ||
|
ac7385391e | ||
|
50a52d79ec | ||
|
d77a1c8cd6 | ||
|
395b9480c5 |
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1,5 +1,3 @@
|
|||||||
* text=auto eol=lf
|
* text=auto eol=lf
|
||||||
binaries/win64/readme.txt eol=crlf
|
|
||||||
binaries/win32/readme.txt eol=crlf
|
|
||||||
*.cmd eol=crlf
|
*.cmd eol=crlf
|
||||||
*.bat eol=crlf
|
*.bat eol=crlf
|
||||||
|
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
blank_issues_enabled: false
|
19
.github/ISSUE_TEMPLATE/issue-warning.md
vendored
Normal file
19
.github/ISSUE_TEMPLATE/issue-warning.md
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
name: bugs
|
||||||
|
about: do not write lame questions
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
1. Здесь не место для вопросов, касающихся компьютерной грамотности и навыков использования ОС
|
||||||
|
2. Здесь не место для вопросов "у меня не работает" без технических подробностей
|
||||||
|
3. Здесь не место для вопросов "как мне открыть ютуб", "что писать в ...", "перестало открываться".
|
||||||
|
4. Здесь не место для обсуждения сборок
|
||||||
|
5. Вирусов здесь нет. У вас либо чья-то сборка, либо ваш антивирус давно пора отправить на покой. Антивирусы в основном жалуются на upx и windivert, которые убраны НЕ будут. upx - это паковщик для сокращения требуемого места на openwrt, windivert - замена iptables для windows, потенциальный инструмент хакера или компонент зловредной программы, но сам по себе вирусом не является. Не согласны - удаляйте софт. За агрессивные наезды "почему автор распространяет вирусы" молча схватите бан.
|
||||||
|
|
||||||
|
Все означенное обсуждать в дискуссиях или на форумах.
|
||||||
|
При нарушении будет закрываться или конвертироваться в дискуссии.
|
||||||
|
Issue только для обсуждения проблем самого софта. Неработа стратегии или ваше неумение настроить - это ваша проблема, а не проблема софта.
|
||||||
|
Однокнопочные решения дают только сборщики, поэтому "открытие сайта" не является функцией программы, и нет смысла жаловаться, что он не открывается. Но можно это обсудить в дискуссиях. Не захламляйте issues !
|
78
.github/workflows/build.yml
vendored
78
.github/workflows/build.yml
vendored
@ -52,6 +52,13 @@ jobs:
|
|||||||
tool: i586-unknown-linux-musl
|
tool: i586-unknown-linux-musl
|
||||||
- arch: x86_64
|
- arch: x86_64
|
||||||
tool: x86_64-unknown-linux-musl
|
tool: x86_64-unknown-linux-musl
|
||||||
|
- arch: lexra
|
||||||
|
tool: mips-linux
|
||||||
|
dir: rsdk-4.6.4-5281-EB-3.10-0.9.33-m32ub-20141001
|
||||||
|
env:
|
||||||
|
CFLAGS: '-march=5281'
|
||||||
|
LDFLAGS: '-lgcc_eh'
|
||||||
|
repo: 'bol-van/build'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@ -60,18 +67,31 @@ jobs:
|
|||||||
|
|
||||||
- name: Set up build tools
|
- name: Set up build tools
|
||||||
env:
|
env:
|
||||||
REPO: 'spvkgn/musl-cross'
|
ARCH: ${{ matrix.arch }}
|
||||||
TOOL: ${{ matrix.tool }}
|
TOOL: ${{ matrix.tool }}
|
||||||
|
REPO: ${{ matrix.arch == 'lexra' && matrix.repo || 'spvkgn/musl-cross' }}
|
||||||
|
DIR: ${{ matrix.arch == 'lexra' && matrix.dir || matrix.tool }}
|
||||||
run: |
|
run: |
|
||||||
sudo apt update -qq && sudo apt install -y libcap-dev
|
if [[ "$ARCH" == lexra ]]; then
|
||||||
|
sudo dpkg --add-architecture i386
|
||||||
|
sudo apt update -qq
|
||||||
|
sudo apt install -y libcap-dev libc6:i386 zlib1g:i386
|
||||||
|
URL=https://github.com/$REPO/raw/refs/heads/master/$DIR.txz
|
||||||
|
else
|
||||||
|
sudo apt update -qq
|
||||||
|
sudo apt install -y libcap-dev
|
||||||
|
URL=https://github.com/$REPO/releases/download/latest/$TOOL.tar.xz
|
||||||
|
fi
|
||||||
mkdir -p $HOME/tools
|
mkdir -p $HOME/tools
|
||||||
wget -qO- https://github.com/$REPO/releases/download/latest/$TOOL.tar.xz | tar -C $HOME/tools -xJ || exit 1
|
wget -qO- $URL | tar -C $HOME/tools -xJ || exit 1
|
||||||
[ -d "$HOME/tools/$TOOL/bin" ] && echo "$HOME/tools/$TOOL/bin" >> $GITHUB_PATH
|
[[ -d "$HOME/tools/$DIR/bin" ]] && echo "$HOME/tools/$DIR/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
env:
|
env:
|
||||||
ARCH: ${{ matrix.arch }}
|
ARCH: ${{ matrix.arch }}
|
||||||
TARGET: ${{ matrix.tool }}
|
TARGET: ${{ matrix.tool }}
|
||||||
|
CFLAGS: ${{ matrix.env.CFLAGS != '' && matrix.env.CFLAGS || null }}
|
||||||
|
LDFLAGS: ${{ matrix.env.LDFLAGS != '' && matrix.env.LDFLAGS || null }}
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
DEPS_DIR=$GITHUB_WORKSPACE/deps
|
DEPS_DIR=$GITHUB_WORKSPACE/deps
|
||||||
@ -81,10 +101,7 @@ jobs:
|
|||||||
export NM=$TARGET-nm
|
export NM=$TARGET-nm
|
||||||
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
|
||||||
# optimize for size
|
|
||||||
export CFLAGS="-Os -flto=auto"
|
|
||||||
export LDFLAGS="-Os"
|
|
||||||
|
|
||||||
# netfilter libs
|
# netfilter libs
|
||||||
wget -qO- https://www.netfilter.org/pub/libnfnetlink/libnfnetlink-1.0.2.tar.bz2 | tar -xj
|
wget -qO- https://www.netfilter.org/pub/libnfnetlink/libnfnetlink-1.0.2.tar.bz2 | tar -xj
|
||||||
@ -94,6 +111,7 @@ jobs:
|
|||||||
for i in libmnl libnfnetlink libnetfilter_queue ; do
|
for i in libmnl libnfnetlink libnetfilter_queue ; do
|
||||||
(
|
(
|
||||||
cd $i-*
|
cd $i-*
|
||||||
|
CFLAGS="-Os -flto=auto $CFLAGS" \
|
||||||
./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
|
||||||
)
|
)
|
||||||
@ -105,6 +123,7 @@ jobs:
|
|||||||
xargs -I{} wget -qO- https://github.com/madler/zlib/archive/refs/tags/{}.tar.gz | tar -xz
|
xargs -I{} wget -qO- https://github.com/madler/zlib/archive/refs/tags/{}.tar.gz | tar -xz
|
||||||
(
|
(
|
||||||
cd zlib-*
|
cd zlib-*
|
||||||
|
CFLAGS="-Os -flto=auto $CFLAGS" \
|
||||||
./configure --prefix= --static
|
./configure --prefix= --static
|
||||||
make install -j$(nproc) DESTDIR=$DEPS_DIR
|
make install -j$(nproc) DESTDIR=$DEPS_DIR
|
||||||
)
|
)
|
||||||
@ -115,8 +134,8 @@ jobs:
|
|||||||
install -Dm644 -t $DEPS_DIR/include/sys /usr/include/x86_64-linux-gnu/sys/queue.h /usr/include/sys/capability.h
|
install -Dm644 -t $DEPS_DIR/include/sys /usr/include/x86_64-linux-gnu/sys/queue.h /usr/include/sys/capability.h
|
||||||
|
|
||||||
# zapret
|
# zapret
|
||||||
CFLAGS="$CFLAGS -static-libgcc -static -I$DEPS_DIR/include" \
|
CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }} -static-libgcc -static -I$DEPS_DIR/include $CFLAGS" \
|
||||||
LDFLAGS="$LDFLAGS -L$DEPS_DIR/lib" \
|
LDFLAGS="-L$DEPS_DIR/lib $LDFLAGS" \
|
||||||
make -C zapret -j$(nproc)
|
make -C zapret -j$(nproc)
|
||||||
tar -C zapret/binaries/my -cJf zapret-linux-$ARCH.tar.xz .
|
tar -C zapret/binaries/my -cJf zapret-linux-$ARCH.tar.xz .
|
||||||
|
|
||||||
@ -136,6 +155,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build zapret
|
- name: Build zapret
|
||||||
run: |
|
run: |
|
||||||
|
export CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }}"
|
||||||
make mac -j$(sysctl -n hw.logicalcpu)
|
make mac -j$(sysctl -n hw.logicalcpu)
|
||||||
tar -C binaries/my -cJf zapret-mac-x64.tar.xz .
|
tar -C binaries/my -cJf zapret-mac-x64.tar.xz .
|
||||||
|
|
||||||
@ -170,7 +190,8 @@ jobs:
|
|||||||
TARGET: ${{ matrix.target }}
|
TARGET: ${{ matrix.target }}
|
||||||
ARCH: ${{ matrix.arch }}
|
ARCH: ${{ matrix.arch }}
|
||||||
run: |
|
run: |
|
||||||
settarget $TARGET-freebsd11 make bsd -j$(nproc) || exit 1
|
export CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }}"
|
||||||
|
settarget $TARGET-freebsd11 make bsd -j$(nproc)
|
||||||
tar -C binaries/my -cJf zapret-freebsd-$ARCH.tar.xz .
|
tar -C binaries/my -cJf zapret-freebsd-$ARCH.tar.xz .
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
@ -203,6 +224,7 @@ jobs:
|
|||||||
- name: Build ip2net, mdig
|
- name: Build ip2net, mdig
|
||||||
shell: msys2 {0}
|
shell: msys2 {0}
|
||||||
run: |
|
run: |
|
||||||
|
export CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }}"
|
||||||
mkdir -p output
|
mkdir -p output
|
||||||
cd zapret
|
cd zapret
|
||||||
mingw32-make -C ip2net win
|
mingw32-make -C ip2net win
|
||||||
@ -259,6 +281,7 @@ jobs:
|
|||||||
shell: C:\cygwin\bin\bash.exe -eo pipefail '{0}'
|
shell: C:\cygwin\bin\bash.exe -eo pipefail '{0}'
|
||||||
run: >-
|
run: >-
|
||||||
export MAKEFLAGS=-j$(nproc) &&
|
export MAKEFLAGS=-j$(nproc) &&
|
||||||
|
export CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }}" &&
|
||||||
cd zapret &&
|
cd zapret &&
|
||||||
make -C nfq ${TARGET} &&
|
make -C nfq ${TARGET} &&
|
||||||
cp -a nfq/winws.exe ../output
|
cp -a nfq/winws.exe ../output
|
||||||
@ -304,11 +327,12 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
env:
|
env:
|
||||||
ABI: ${{ matrix.abi }}
|
ABI: ${{ matrix.abi }}
|
||||||
|
API: 21
|
||||||
TARGET: ${{ matrix.target }}
|
TARGET: ${{ matrix.target }}
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
run: |
|
run: |
|
||||||
DEPS_DIR=$GITHUB_WORKSPACE/deps
|
DEPS_DIR=$GITHUB_WORKSPACE/deps
|
||||||
export TOOLCHAIN=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64
|
export TOOLCHAIN=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64
|
||||||
export API=21
|
|
||||||
export CC="$TOOLCHAIN/bin/clang --target=$TARGET$API"
|
export CC="$TOOLCHAIN/bin/clang --target=$TARGET$API"
|
||||||
export AR=$TOOLCHAIN/bin/llvm-ar
|
export AR=$TOOLCHAIN/bin/llvm-ar
|
||||||
export AS=$CC
|
export AS=$CC
|
||||||
@ -317,10 +341,6 @@ jobs:
|
|||||||
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
|
||||||
|
|
||||||
# optimize for size
|
|
||||||
export CFLAGS="-Os -flto=auto"
|
|
||||||
export LDFLAGS="-Os"
|
|
||||||
|
|
||||||
# netfilter libs
|
# netfilter libs
|
||||||
wget -qO- https://www.netfilter.org/pub/libnfnetlink/libnfnetlink-1.0.2.tar.bz2 | tar -xj
|
wget -qO- https://www.netfilter.org/pub/libnfnetlink/libnfnetlink-1.0.2.tar.bz2 | tar -xj
|
||||||
wget -qO- https://www.netfilter.org/pub/libmnl/libmnl-1.0.5.tar.bz2 | tar -xj
|
wget -qO- https://www.netfilter.org/pub/libmnl/libmnl-1.0.5.tar.bz2 | tar -xj
|
||||||
@ -330,7 +350,7 @@ jobs:
|
|||||||
for i in libmnl libnfnetlink libnetfilter_queue ; do
|
for i in libmnl libnfnetlink libnetfilter_queue ; do
|
||||||
(
|
(
|
||||||
cd $i-*
|
cd $i-*
|
||||||
CFLAGS="$CFLAGS -Wno-implicit-function-declaration" \
|
CFLAGS="-Os -flto=auto -Wno-implicit-function-declaration" \
|
||||||
./configure --prefix= --host=$TARGET --enable-static --disable-shared --disable-dependency-tracking
|
./configure --prefix= --host=$TARGET --enable-static --disable-shared --disable-dependency-tracking
|
||||||
make install -j$(nproc) DESTDIR=$DEPS_DIR
|
make install -j$(nproc) DESTDIR=$DEPS_DIR
|
||||||
)
|
)
|
||||||
@ -338,8 +358,15 @@ jobs:
|
|||||||
done
|
done
|
||||||
|
|
||||||
# zapret
|
# zapret
|
||||||
CFLAGS="$CFLAGS -I$DEPS_DIR/include" LDFLAGS="$LDFLAGS -L$DEPS_DIR/lib" \
|
CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }} -I$DEPS_DIR/include" \
|
||||||
|
LDFLAGS="-L$DEPS_DIR/lib" \
|
||||||
make -C zapret android -j$(nproc)
|
make -C zapret android -j$(nproc)
|
||||||
|
|
||||||
|
# strip unwanted ELF sections to prevent warnings on old Android versions
|
||||||
|
gh api repos/termux/termux-elf-cleaner/releases/latest --jq '.tag_name' |\
|
||||||
|
xargs -I{} wget -O elf-cleaner https://github.com/termux/termux-elf-cleaner/releases/download/{}/termux-elf-cleaner
|
||||||
|
chmod +x elf-cleaner
|
||||||
|
./elf-cleaner --api-level $API zapret/binaries/my/*
|
||||||
zip zapret-android-$ABI.zip -j zapret/binaries/my/*
|
zip zapret-android-$ABI.zip -j zapret/binaries/my/*
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
@ -374,6 +401,7 @@ jobs:
|
|||||||
uses: crazy-max/ghaction-upx@v3
|
uses: crazy-max/ghaction-upx@v3
|
||||||
with:
|
with:
|
||||||
install-only: true
|
install-only: true
|
||||||
|
version: v4.2.4
|
||||||
|
|
||||||
- name: Prepare binaries
|
- name: Prepare binaries
|
||||||
shell: bash
|
shell: bash
|
||||||
@ -391,7 +419,7 @@ jobs:
|
|||||||
if [[ $dir == *-linux-x86_64 ]]; then
|
if [[ $dir == *-linux-x86_64 ]]; then
|
||||||
tar -C $dir -czvf $dir/tpws_wsl.tgz tpws
|
tar -C $dir -czvf $dir/tpws_wsl.tgz tpws
|
||||||
run_upx $dir/*
|
run_upx $dir/*
|
||||||
elif [[ $dir =~ linux ]] && [[ $dir != *-linux-mips64 ]]; then
|
elif [[ $dir =~ linux ]] && [[ $dir != *-linux-mips64 ]] && [[ $dir != *-linux-lexra ]]; then
|
||||||
run_upx $dir/*
|
run_upx $dir/*
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
@ -423,6 +451,7 @@ jobs:
|
|||||||
*-linux-ppc ) run_dir ppc ;;
|
*-linux-ppc ) run_dir ppc ;;
|
||||||
*-linux-x86 ) run_dir x86 ;;
|
*-linux-x86 ) run_dir x86 ;;
|
||||||
*-linux-x86_64 ) run_dir x86_64 ;;
|
*-linux-x86_64 ) run_dir x86_64 ;;
|
||||||
|
*-linux-lexra ) run_dir lexra ;;
|
||||||
*-mac-x64 ) run_dir mac64 ;;
|
*-mac-x64 ) run_dir mac64 ;;
|
||||||
*-win-x86 ) run_dir win32 ;;
|
*-win-x86 ) run_dir win32 ;;
|
||||||
*-win-x86_64 ) run_dir win64 ;;
|
*-win-x86_64 ) run_dir win64 ;;
|
||||||
@ -434,8 +463,16 @@ jobs:
|
|||||||
- name: Create release bundles
|
- name: Create release bundles
|
||||||
run: |
|
run: |
|
||||||
rm -rf ${{ env.repo_dir }}/.git*
|
rm -rf ${{ env.repo_dir }}/.git*
|
||||||
tar -czf ${{ env.repo_dir }}.tar.gz ${{ env.repo_dir }}
|
find ${{ env.repo_dir }}/binaries -type f -exec sha256sum {} \; >sha256sum.txt
|
||||||
|
tar --owner=0 --group=0 -czf ${{ env.repo_dir }}.tar.gz ${{ env.repo_dir }}
|
||||||
zip -qr ${{ env.repo_dir }}.zip ${{ env.repo_dir }}
|
zip -qr ${{ env.repo_dir }}.zip ${{ env.repo_dir }}
|
||||||
|
(
|
||||||
|
cd ${{ env.repo_dir }}
|
||||||
|
rm -rf binaries/{android*,freebsd*,mac*,win*,x86_64/tpws_wsl.tgz} \
|
||||||
|
init.d/{openrc,macos,pfsense,runit,s6,systemd} \
|
||||||
|
tpws nfq ip2net mdig docs files/huawei Makefile
|
||||||
|
)
|
||||||
|
tar --owner=0 --group=0 -czf ${{ env.repo_dir }}-openwrt-embedded.tar.gz ${{ env.repo_dir }}
|
||||||
|
|
||||||
- name: Upload release assets
|
- name: Upload release assets
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v2
|
||||||
@ -448,3 +485,4 @@ jobs:
|
|||||||
files: |
|
files: |
|
||||||
zapret*.tar.gz
|
zapret*.tar.gz
|
||||||
zapret*.zip
|
zapret*.zip
|
||||||
|
sha256sum.txt
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,9 +4,9 @@ mdig/mdig
|
|||||||
nfq/dvtws
|
nfq/dvtws
|
||||||
nfq/nfqws
|
nfq/nfqws
|
||||||
nfq/winws.exe
|
nfq/winws.exe
|
||||||
|
nfq/WinDivert*
|
||||||
tpws/tpws
|
tpws/tpws
|
||||||
binaries/my/
|
binaries/my/
|
||||||
init.d/**/custom
|
|
||||||
ipset/zapret-ip*.txt
|
ipset/zapret-ip*.txt
|
||||||
ipset/zapret-ip*.gz
|
ipset/zapret-ip*.gz
|
||||||
ipset/zapret-hosts*.txt
|
ipset/zapret-hosts*.txt
|
||||||
|
13
Makefile
13
Makefile
@ -15,6 +15,19 @@ all: clean
|
|||||||
done \
|
done \
|
||||||
done
|
done
|
||||||
|
|
||||||
|
systemd: clean
|
||||||
|
@mkdir -p "$(TGT)"; \
|
||||||
|
for dir in $(DIRS); do \
|
||||||
|
find "$$dir" -type f \( -name "*.c" -o -name "*.h" -o -name "*akefile" \) -exec chmod -x {} \; ; \
|
||||||
|
$(MAKE) -C "$$dir" systemd || exit; \
|
||||||
|
for exe in "$$dir/"*; do \
|
||||||
|
if [ -f "$$exe" ] && [ -x "$$exe" ]; then \
|
||||||
|
mv -f "$$exe" "${TGT}" ; \
|
||||||
|
ln -fs "../${TGT}/$$(basename "$$exe")" "$$exe" ; \
|
||||||
|
fi \
|
||||||
|
done \
|
||||||
|
done
|
||||||
|
|
||||||
android: clean
|
android: clean
|
||||||
@mkdir -p "$(TGT)"; \
|
@mkdir -p "$(TGT)"; \
|
||||||
for dir in $(DIRS); do \
|
for dir in $(DIRS); do \
|
||||||
|
333
blockcheck.sh
333
blockcheck.sh
@ -23,6 +23,7 @@ CURL=${CURL:-curl}
|
|||||||
. "$ZAPRET_BASE/common/fwtype.sh"
|
. "$ZAPRET_BASE/common/fwtype.sh"
|
||||||
. "$ZAPRET_BASE/common/virt.sh"
|
. "$ZAPRET_BASE/common/virt.sh"
|
||||||
|
|
||||||
|
DOMAINS_DEFAULT=${DOMAINS_DEFAULT:-rutracker.org}
|
||||||
QNUM=${QNUM:-59780}
|
QNUM=${QNUM:-59780}
|
||||||
SOCKS_PORT=${SOCKS_PORT:-1993}
|
SOCKS_PORT=${SOCKS_PORT:-1993}
|
||||||
TPWS_UID=${TPWS_UID:-1}
|
TPWS_UID=${TPWS_UID:-1}
|
||||||
@ -35,9 +36,9 @@ MDIG=${MDIG:-${ZAPRET_BASE}/mdig/mdig}
|
|||||||
DESYNC_MARK=0x10000000
|
DESYNC_MARK=0x10000000
|
||||||
IPFW_RULE_NUM=${IPFW_RULE_NUM:-1}
|
IPFW_RULE_NUM=${IPFW_RULE_NUM:-1}
|
||||||
IPFW_DIVERT_PORT=${IPFW_DIVERT_PORT:-59780}
|
IPFW_DIVERT_PORT=${IPFW_DIVERT_PORT:-59780}
|
||||||
DOMAINS=${DOMAINS:-rutracker.org}
|
|
||||||
CURL_MAX_TIME=${CURL_MAX_TIME:-2}
|
CURL_MAX_TIME=${CURL_MAX_TIME:-2}
|
||||||
CURL_MAX_TIME_QUIC=${CURL_MAX_TIME_QUIC:-$CURL_MAX_TIME}
|
CURL_MAX_TIME_QUIC=${CURL_MAX_TIME_QUIC:-$CURL_MAX_TIME}
|
||||||
|
CURL_MAX_TIME_DOH=${CURL_MAX_TIME_DOH:-2}
|
||||||
MIN_TTL=${MIN_TTL:-1}
|
MIN_TTL=${MIN_TTL:-1}
|
||||||
MAX_TTL=${MAX_TTL:-12}
|
MAX_TTL=${MAX_TTL:-12}
|
||||||
USER_AGENT=${USER_AGENT:-Mozilla}
|
USER_AGENT=${USER_AGENT:-Mozilla}
|
||||||
@ -45,8 +46,9 @@ HTTP_PORT=${HTTP_PORT:-80}
|
|||||||
HTTPS_PORT=${HTTPS_PORT:-443}
|
HTTPS_PORT=${HTTPS_PORT:-443}
|
||||||
QUIC_PORT=${QUIC_PORT:-443}
|
QUIC_PORT=${QUIC_PORT:-443}
|
||||||
UNBLOCKED_DOM=${UNBLOCKED_DOM:-iana.org}
|
UNBLOCKED_DOM=${UNBLOCKED_DOM:-iana.org}
|
||||||
|
PARALLEL_OUT=/tmp/zapret_parallel
|
||||||
|
|
||||||
HDRTEMP=/tmp/zapret-hdr.txt
|
HDRTEMP=/tmp/zapret-hdr
|
||||||
|
|
||||||
NFT_TABLE=blockcheck
|
NFT_TABLE=blockcheck
|
||||||
|
|
||||||
@ -77,9 +79,11 @@ exitp()
|
|||||||
{
|
{
|
||||||
local A
|
local A
|
||||||
|
|
||||||
echo
|
[ "$BATCH" = 1 ] || {
|
||||||
echo press enter to continue
|
echo
|
||||||
read A
|
echo press enter to continue
|
||||||
|
read A
|
||||||
|
}
|
||||||
exit $1
|
exit $1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +216,7 @@ doh_resolve()
|
|||||||
# $1 - ip version 4/6
|
# $1 - ip version 4/6
|
||||||
# $2 - hostname
|
# $2 - hostname
|
||||||
# $3 - doh server URL. use $DOH_SERVER if empty
|
# $3 - doh server URL. use $DOH_SERVER if empty
|
||||||
$MDIG --family=$1 --dns-make-query=$2 | curl -s --data-binary @- -H "Content-Type: application/dns-message" "${3:-$DOH_SERVER}" | $MDIG --dns-parse-query
|
$MDIG --family=$1 --dns-make-query=$2 | $CURL --max-time $CURL_MAX_TIME_DOH -s --data-binary @- -H "Content-Type: application/dns-message" "${3:-$DOH_SERVER}" | $MDIG --dns-parse-query
|
||||||
}
|
}
|
||||||
doh_find_working()
|
doh_find_working()
|
||||||
{
|
{
|
||||||
@ -337,12 +341,19 @@ netcat_test()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tpws_can_fix_seg()
|
||||||
|
{
|
||||||
|
# fix-seg requires kernel 4.6+
|
||||||
|
"$TPWS" --port 1 --dry-run --fix-seg >/dev/null 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
check_system()
|
check_system()
|
||||||
{
|
{
|
||||||
echo \* checking system
|
echo \* checking system
|
||||||
|
|
||||||
UNAME=$(uname)
|
UNAME=$(uname)
|
||||||
SUBSYS=
|
SUBSYS=
|
||||||
|
FIX_SEG=
|
||||||
local s
|
local s
|
||||||
|
|
||||||
# can be passed FWTYPE=iptables to override default nftables preference
|
# can be passed FWTYPE=iptables to override default nftables preference
|
||||||
@ -350,6 +361,14 @@ check_system()
|
|||||||
Linux)
|
Linux)
|
||||||
PKTWS="$NFQWS"
|
PKTWS="$NFQWS"
|
||||||
PKTWSD=nfqws
|
PKTWSD=nfqws
|
||||||
|
if [ -x "$TPWS" ] ; then
|
||||||
|
if tpws_can_fix_seg ; then
|
||||||
|
echo tpws supports --fix-seg on this system
|
||||||
|
FIX_SEG='--fix-seg'
|
||||||
|
else
|
||||||
|
echo tpws does not support --fix-seg on this system
|
||||||
|
fi
|
||||||
|
fi
|
||||||
linux_fwtype
|
linux_fwtype
|
||||||
[ "$FWTYPE" = iptables -o "$FWTYPE" = nftables ] || {
|
[ "$FWTYPE" = iptables -o "$FWTYPE" = nftables ] || {
|
||||||
echo firewall type $FWTYPE not supported in $UNAME
|
echo firewall type $FWTYPE not supported in $UNAME
|
||||||
@ -560,7 +579,7 @@ curl_supports_tls13()
|
|||||||
[ $? = 2 ] && return 1
|
[ $? = 2 ] && return 1
|
||||||
# curl can have tlsv1.3 key present but ssl library without TLS 1.3 support
|
# curl can have tlsv1.3 key present but ssl library without TLS 1.3 support
|
||||||
# this is online test because there's no other way to trigger library incompatibility case
|
# this is online test because there's no other way to trigger library incompatibility case
|
||||||
$CURL --tlsv1.3 --max-time $CURL_MAX_TIME -Is -o /dev/null https://iana.org 2>/dev/null
|
$CURL --tlsv1.3 --max-time 1 -Is -o /dev/null https://iana.org 2>/dev/null
|
||||||
r=$?
|
r=$?
|
||||||
[ $r != 4 -a $r != 35 ]
|
[ $r != 4 -a $r != 35 ]
|
||||||
}
|
}
|
||||||
@ -651,28 +670,28 @@ curl_test_http()
|
|||||||
# $3 - subst ip
|
# $3 - subst ip
|
||||||
# $4 - "detail" - detail info
|
# $4 - "detail" - detail info
|
||||||
|
|
||||||
local code loc
|
local code loc hdrt="${HDRTEMP}_${!:-$$}.txt"
|
||||||
curl_probe $1 $2 $HTTP_PORT "$3" -SsD "$HDRTEMP" -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT "http://$2" -o /dev/null 2>&1 || {
|
curl_probe $1 $2 $HTTP_PORT "$3" -SsD "$hdrt" -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT "http://$2" -o /dev/null 2>&1 || {
|
||||||
code=$?
|
code=$?
|
||||||
rm -f "$HDRTEMP"
|
rm -f "$hdrt"
|
||||||
return $code
|
return $code
|
||||||
}
|
}
|
||||||
if [ "$4" = "detail" ] ; then
|
if [ "$4" = "detail" ] ; then
|
||||||
head -n 1 "$HDRTEMP"
|
head -n 1 "$hdrt"
|
||||||
grep "^[lL]ocation:" "$HDRTEMP"
|
grep "^[lL]ocation:" "$hdrt"
|
||||||
else
|
else
|
||||||
code=$(hdrfile_http_code "$HDRTEMP")
|
code=$(hdrfile_http_code "$hdrt")
|
||||||
[ "$code" = 301 -o "$code" = 302 -o "$code" = 307 -o "$code" = 308 ] && {
|
[ "$code" = 301 -o "$code" = 302 -o "$code" = 307 -o "$code" = 308 ] && {
|
||||||
loc=$(hdrfile_location "$HDRTEMP")
|
loc=$(hdrfile_location "$hdrt")
|
||||||
echo "$loc" | grep -qE "^https?://.*$2(/|$)" ||
|
echo "$loc" | grep -qE "^https?://.*$2(/|$)" ||
|
||||||
echo "$loc" | grep -vqE '^https?://' || {
|
echo "$loc" | grep -vqE '^https?://' || {
|
||||||
echo suspicious redirection $code to : $loc
|
echo suspicious redirection $code to : $loc
|
||||||
rm -f "$HDRTEMP"
|
rm -f "$hdrt"
|
||||||
return 254
|
return 254
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
rm -f "$HDRTEMP"
|
rm -f "$hdrt"
|
||||||
[ "$code" = 400 ] && {
|
[ "$code" = 400 ] && {
|
||||||
# this can often happen if the server receives fake packets it should not receive
|
# this can often happen if the server receives fake packets it should not receive
|
||||||
echo http code $code. likely the server receives fakes.
|
echo http code $code. likely the server receives fakes.
|
||||||
@ -964,18 +983,38 @@ curl_test()
|
|||||||
# $2 - domain
|
# $2 - domain
|
||||||
# $3 - subst ip
|
# $3 - subst ip
|
||||||
# $4 - param of test function
|
# $4 - param of test function
|
||||||
local code=0 n=0
|
local code=0 n=0 p pids
|
||||||
|
|
||||||
while [ $n -lt $REPEATS ]; do
|
if [ "$PARALLEL" = 1 ]; then
|
||||||
n=$(($n+1))
|
rm -f "${PARALLEL_OUT}"*
|
||||||
[ $REPEATS -gt 1 ] && printf "[attempt $n] "
|
for n in $(seq -s ' ' 1 $REPEATS); do
|
||||||
if $1 "$IPV" $2 $3 "$4" ; then
|
$1 "$IPV" $2 $3 "$4" >"${PARALLEL_OUT}_$n" &
|
||||||
[ $REPEATS -gt 1 ] && echo 'AVAILABLE'
|
pids="${pids:+$pids }$!"
|
||||||
else
|
done
|
||||||
code=$?
|
n=1
|
||||||
[ "$SCANLEVEL" = quick ] && break
|
for p in $pids; do
|
||||||
fi
|
[ $REPEATS -gt 1 ] && printf "[attempt $n] "
|
||||||
done
|
if wait $p; then
|
||||||
|
[ $REPEATS -gt 1 ] && echo 'AVAILABLE'
|
||||||
|
else
|
||||||
|
code=$?
|
||||||
|
cat "${PARALLEL_OUT}_$n"
|
||||||
|
fi
|
||||||
|
n=$(($n+1))
|
||||||
|
done
|
||||||
|
rm -f "${PARALLEL_OUT}"*
|
||||||
|
else
|
||||||
|
while [ $n -lt $REPEATS ]; do
|
||||||
|
n=$(($n+1))
|
||||||
|
[ $REPEATS -gt 1 ] && printf "[attempt $n] "
|
||||||
|
if $1 "$IPV" $2 $3 "$4" ; then
|
||||||
|
[ $REPEATS -gt 1 ] && echo 'AVAILABLE'
|
||||||
|
else
|
||||||
|
code=$?
|
||||||
|
[ "$SCANLEVEL" = quick ] && break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
[ "$4" = detail ] || {
|
[ "$4" = detail ] || {
|
||||||
if [ $code = 254 ]; then
|
if [ $code = 254 ]; then
|
||||||
echo "UNAVAILABLE"
|
echo "UNAVAILABLE"
|
||||||
@ -1011,11 +1050,10 @@ tpws_curl_test()
|
|||||||
echo - checking tpws $3 $4 $5 $6 $7 $8 $9${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}
|
echo - checking tpws $3 $4 $5 $6 $7 $8 $9${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}
|
||||||
local ALL_PROXY="socks5://127.0.0.1:$SOCKS_PORT"
|
local ALL_PROXY="socks5://127.0.0.1:$SOCKS_PORT"
|
||||||
ws_curl_test tpws_start "$@"${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}
|
ws_curl_test tpws_start "$@"${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}
|
||||||
local code=$?
|
local testf=$1 dom=$2 strategy code=$?
|
||||||
[ "$code" = 0 ] && {
|
[ "$code" = 0 ] && {
|
||||||
local testf=$1 dom=$2
|
|
||||||
shift; shift;
|
shift; shift;
|
||||||
local strategy="$@"
|
strategy="$@"
|
||||||
strategy_append_extra_tpws
|
strategy_append_extra_tpws
|
||||||
report_append "ipv${IPV} $dom $testf : tpws ${WF:+$WF }$strategy"
|
report_append "ipv${IPV} $dom $testf : tpws ${WF:+$WF }$strategy"
|
||||||
}
|
}
|
||||||
@ -1028,11 +1066,10 @@ pktws_curl_test()
|
|||||||
# $3,$4,$5, ... - nfqws/dvtws params
|
# $3,$4,$5, ... - nfqws/dvtws params
|
||||||
echo - checking $PKTWSD ${WF:+$WF }$3 $4 $5 $6 $7 $8 $9${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}
|
echo - checking $PKTWSD ${WF:+$WF }$3 $4 $5 $6 $7 $8 $9${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}
|
||||||
ws_curl_test pktws_start "$@"${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}
|
ws_curl_test pktws_start "$@"${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}
|
||||||
local code=$?
|
local testf=$1 dom=$2 strategy code=$?
|
||||||
[ "$code" = 0 ] && {
|
[ "$code" = 0 ] && {
|
||||||
local testf=$1 dom=$2
|
|
||||||
shift; shift;
|
shift; shift;
|
||||||
local strategy="$@"
|
strategy="$@"
|
||||||
strategy_append_extra_pktws
|
strategy_append_extra_pktws
|
||||||
report_append "ipv${IPV} $dom $testf : $PKTWSD ${WF:+$WF }$strategy"
|
report_append "ipv${IPV} $dom $testf : $PKTWSD ${WF:+$WF }$strategy"
|
||||||
}
|
}
|
||||||
@ -1112,6 +1149,10 @@ test_has_split()
|
|||||||
{
|
{
|
||||||
contains "$1" split || contains "$1" disorder
|
contains "$1" split || contains "$1" disorder
|
||||||
}
|
}
|
||||||
|
test_has_fakedsplit()
|
||||||
|
{
|
||||||
|
contains "$1" fakedsplit || contains "$1" fakeddisorder
|
||||||
|
}
|
||||||
test_has_fake()
|
test_has_fake()
|
||||||
{
|
{
|
||||||
[ "$1" = fake ] || starts_with "$1" fake,
|
[ "$1" = fake ] || starts_with "$1" fake,
|
||||||
@ -1119,7 +1160,10 @@ test_has_fake()
|
|||||||
warn_fool()
|
warn_fool()
|
||||||
{
|
{
|
||||||
case "$1" in
|
case "$1" in
|
||||||
md5sig) echo 'WARNING ! although md5sig fooling worked it will not work on all sites. it typically works only on linux servers.' ;;
|
md5sig) echo 'WARNING ! although md5sig fooling worked it will not work on all sites. it typically works only on linux servers.'
|
||||||
|
[ "$2" = "fakedsplit" -o "$2" = "fakeddisorder" ] && \
|
||||||
|
echo "WARNING ! fakedsplit/fakeddisorder with md5sig fooling and low split position causes MTU overflow with multi-segment TLS (kyber)"
|
||||||
|
;;
|
||||||
datanoack) echo 'WARNING ! although datanoack fooling worked it may break NAT and may only work with external IP. Additionally it may require nftables to work correctly.' ;;
|
datanoack) echo 'WARNING ! although datanoack fooling worked it may break NAT and may only work with external IP. Additionally it may require nftables to work correctly.' ;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@ -1131,18 +1175,24 @@ pktws_curl_test_update_vary()
|
|||||||
# $4 - desync mode
|
# $4 - desync mode
|
||||||
# $5,$6,... - strategy
|
# $5,$6,... - strategy
|
||||||
|
|
||||||
local testf=$1 sec=$2 domain=$3 desync=$4 proto zerofake= splits= pos fake ret=1
|
local testf=$1 sec=$2 domain=$3 desync=$4 proto zerofake= tlsmod= splits= pos fake ret=1
|
||||||
|
|
||||||
shift; shift; shift; shift
|
shift; shift; shift; shift
|
||||||
|
|
||||||
proto=http
|
proto=http
|
||||||
[ "$sec" = 0 ] || proto=tls
|
[ "$sec" = 0 ] || proto=tls
|
||||||
test_has_fake $desync && zerofake="--dpi-desync-fake-$proto=0x00000000"
|
test_has_fake $desync && {
|
||||||
test_has_split $desync && {
|
zerofake="--dpi-desync-fake-$proto=0x00000000"
|
||||||
|
[ "$sec" = 0 ] || tlsmod="--dpi-desync-fake-tls-mod=rnd,dupsid,rndsni,padencap"
|
||||||
|
}
|
||||||
|
if test_has_fakedsplit $desync ; then
|
||||||
|
splits="method+2 midsld"
|
||||||
|
[ "$sec" = 0 ] || splits="1 midsld"
|
||||||
|
elif test_has_split $desync ; then
|
||||||
splits="method+2 midsld"
|
splits="method+2 midsld"
|
||||||
[ "$sec" = 0 ] || splits="1 midsld 1,midsld"
|
[ "$sec" = 0 ] || splits="1 midsld 1,midsld"
|
||||||
}
|
fi
|
||||||
for fake in '' $zerofake ; do
|
for fake in '' $zerofake $tlsmod ; do
|
||||||
if [ -n "$splits" ]; then
|
if [ -n "$splits" ]; then
|
||||||
for pos in $splits ; do
|
for pos in $splits ; do
|
||||||
pktws_curl_test_update $testf $domain --dpi-desync=$desync "$@" --dpi-desync-split-pos=$pos $fake && {
|
pktws_curl_test_update $testf $domain --dpi-desync=$desync "$@" --dpi-desync-split-pos=$pos $fake && {
|
||||||
@ -1173,7 +1223,7 @@ pktws_check_domain_http_bypass_()
|
|||||||
local splits_tls='2 1 sniext+1 sniext+4 host+1 midsld 1,midsld 1,sniext+1,host+1,midsld-2,midsld,midsld+2,endhost-1'
|
local splits_tls='2 1 sniext+1 sniext+4 host+1 midsld 1,midsld 1,sniext+1,host+1,midsld-2,midsld,midsld+2,endhost-1'
|
||||||
|
|
||||||
[ "$sec" = 0 ] && {
|
[ "$sec" = 0 ] && {
|
||||||
for s in '--hostcase' '--hostspell=hoSt' '--hostnospace' '--domcase'; do
|
for s in '--hostcase' '--hostspell=hoSt' '--hostnospace' '--domcase' '--methodeol'; do
|
||||||
pktws_curl_test_update $1 $3 $s
|
pktws_curl_test_update $1 $3 $s
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
@ -1240,7 +1290,7 @@ pktws_check_domain_http_bypass_()
|
|||||||
[ "$IPV" = 6 ] && f="$f hopbyhop hopbyhop2"
|
[ "$IPV" = 6 ] && f="$f hopbyhop hopbyhop2"
|
||||||
for fooling in $f; do
|
for fooling in $f; do
|
||||||
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fooling=$fooling $e && {
|
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fooling=$fooling $e && {
|
||||||
warn_fool $fooling
|
warn_fool $fooling $desync
|
||||||
[ "$SCANLEVEL" = quick ] && return
|
[ "$SCANLEVEL" = quick ] && return
|
||||||
need_wssize=0
|
need_wssize=0
|
||||||
}
|
}
|
||||||
@ -1395,6 +1445,11 @@ warn_mss()
|
|||||||
[ -n "$1" ] && echo 'WARNING ! although mss worked it may not work on all sites and will likely cause significant slowdown. it may only be required for TLS1.2, not TLS1.3'
|
[ -n "$1" ] && echo 'WARNING ! although mss worked it may not work on all sites and will likely cause significant slowdown. it may only be required for TLS1.2, not TLS1.3'
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
fix_seg()
|
||||||
|
{
|
||||||
|
# $1 - split-pos
|
||||||
|
[ -n "$FIX_SEG" ] && contains "$1" , && echo "$FIX_SEG"
|
||||||
|
}
|
||||||
|
|
||||||
tpws_check_domain_http_bypass_()
|
tpws_check_domain_http_bypass_()
|
||||||
{
|
{
|
||||||
@ -1420,7 +1475,7 @@ tpws_check_domain_http_bypass_()
|
|||||||
done
|
done
|
||||||
for s2 in '' '--hostcase' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
|
for s2 in '' '--hostcase' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
|
||||||
for s in $splits_http ; do
|
for s in $splits_http ; do
|
||||||
tpws_curl_test_update $1 $3 --split-pos=$s $s2 && [ "$SCANLEVEL" != force ] && {
|
tpws_curl_test_update $1 $3 --split-pos=$s $(fix_seg $s) $s2 && [ "$SCANLEVEL" != force ] && {
|
||||||
[ "$SCANLEVEL" = quick ] && return
|
[ "$SCANLEVEL" = quick ] && return
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -1435,7 +1490,7 @@ tpws_check_domain_http_bypass_()
|
|||||||
s3=${mss:+--mss=$mss}
|
s3=${mss:+--mss=$mss}
|
||||||
for s2 in '' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
|
for s2 in '' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
|
||||||
for pos in $splits_tls; do
|
for pos in $splits_tls; do
|
||||||
tpws_curl_test_update $1 $3 --split-pos=$pos $s2 $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
|
tpws_curl_test_update $1 $3 --split-pos=$pos $(fix_seg $pos) $s2 $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
|
||||||
[ "$SCANLEVEL" = quick ] && return
|
[ "$SCANLEVEL" = quick ] && return
|
||||||
need_mss=0
|
need_mss=0
|
||||||
break
|
break
|
||||||
@ -1443,7 +1498,7 @@ tpws_check_domain_http_bypass_()
|
|||||||
done
|
done
|
||||||
done
|
done
|
||||||
for s in '' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
|
for s in '' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
|
||||||
for s2 in '--tlsrec=midsld' '--tlsrec=sniext+1 --split-pos=midsld' '--tlsrec=sniext+4 --split-pos=midsld' '--tlsrec=sniext+1 --split-pos=1,midsld' '--tlsrec=sniext+4 --split-pos=1,midsld' ; do
|
for s2 in '--tlsrec=midsld' '--tlsrec=sniext+1 --split-pos=midsld' '--tlsrec=sniext+4 --split-pos=midsld' "--tlsrec=sniext+1 --split-pos=1,midsld $FIX_SEG" "--tlsrec=sniext+4 --split-pos=1,midsld $FIX_SEG" ; do
|
||||||
tpws_curl_test_update $1 $3 $s2 $s $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
|
tpws_curl_test_update $1 $3 $s2 $s $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
|
||||||
[ "$SCANLEVEL" = quick ] && return
|
[ "$SCANLEVEL" = quick ] && return
|
||||||
need_mss=0
|
need_mss=0
|
||||||
@ -1546,7 +1601,7 @@ check_domain_http_tcp()
|
|||||||
|
|
||||||
check_domain_prolog $1 $2 $4 || return
|
check_domain_prolog $1 $2 $4 || return
|
||||||
|
|
||||||
check_dpi_ip_block $1 $4
|
[ "$SKIP_IPBLOCK" = 1 ] || check_dpi_ip_block $1 $4
|
||||||
|
|
||||||
[ "$SKIP_TPWS" = 1 ] || {
|
[ "$SKIP_TPWS" = 1 ] || {
|
||||||
echo
|
echo
|
||||||
@ -1592,22 +1647,22 @@ check_domain_http_udp()
|
|||||||
check_domain_http()
|
check_domain_http()
|
||||||
{
|
{
|
||||||
# $1 - domain
|
# $1 - domain
|
||||||
check_domain_http_tcp curl_test_http 80 0 $1
|
check_domain_http_tcp curl_test_http $HTTP_PORT 0 $1
|
||||||
}
|
}
|
||||||
check_domain_https_tls12()
|
check_domain_https_tls12()
|
||||||
{
|
{
|
||||||
# $1 - domain
|
# $1 - domain
|
||||||
check_domain_http_tcp curl_test_https_tls12 443 1 $1
|
check_domain_http_tcp curl_test_https_tls12 $HTTPS_PORT 1 $1
|
||||||
}
|
}
|
||||||
check_domain_https_tls13()
|
check_domain_https_tls13()
|
||||||
{
|
{
|
||||||
# $1 - domain
|
# $1 - domain
|
||||||
check_domain_http_tcp curl_test_https_tls13 443 2 $1
|
check_domain_http_tcp curl_test_https_tls13 $HTTPS_PORT 2 $1
|
||||||
}
|
}
|
||||||
check_domain_http3()
|
check_domain_http3()
|
||||||
{
|
{
|
||||||
# $1 - domain
|
# $1 - domain
|
||||||
check_domain_http_udp curl_test_http3 443 $1
|
check_domain_http_udp curl_test_http3 $QUIC_PORT $1
|
||||||
}
|
}
|
||||||
|
|
||||||
configure_ip_version()
|
configure_ip_version()
|
||||||
@ -1702,76 +1757,119 @@ ask_params()
|
|||||||
exitp 1
|
exitp 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
echo "specify domain(s) to test. multiple domains are space separated."
|
|
||||||
printf "domain(s) (default: $DOMAINS) : "
|
|
||||||
local dom
|
local dom
|
||||||
read dom
|
[ -n "$DOMAINS" ] || {
|
||||||
[ -n "$dom" ] && DOMAINS="$dom"
|
DOMAINS="$DOMAINS_DEFAULT"
|
||||||
|
[ "$BATCH" = 1 ] || {
|
||||||
|
echo "specify domain(s) to test. multiple domains are space separated."
|
||||||
|
printf "domain(s) (default: $DOMAINS) : "
|
||||||
|
read dom
|
||||||
|
[ -n "$dom" ] && DOMAINS="$dom"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
local IPVS_def=4
|
local IPVS_def=4
|
||||||
# yandex public dns
|
[ -n "$IPVS" ] || {
|
||||||
pingtest 6 2a02:6b8::feed:0ff && IPVS_def=46
|
# yandex public dns
|
||||||
printf "ip protocol version(s) - 4, 6 or 46 for both (default: $IPVS_def) : "
|
pingtest 6 2a02:6b8::feed:0ff && IPVS_def=46
|
||||||
read IPVS
|
[ "$BATCH" = 1 ] || {
|
||||||
[ -n "$IPVS" ] || IPVS=$IPVS_def
|
printf "ip protocol version(s) - 4, 6 or 46 for both (default: $IPVS_def) : "
|
||||||
[ "$IPVS" = 4 -o "$IPVS" = 6 -o "$IPVS" = 46 ] || {
|
read IPVS
|
||||||
echo 'invalid ip version(s). should be 4, 6 or 46.'
|
}
|
||||||
exitp 1
|
[ -n "$IPVS" ] || IPVS=$IPVS_def
|
||||||
|
[ "$IPVS" = 4 -o "$IPVS" = 6 -o "$IPVS" = 46 ] || {
|
||||||
|
echo 'invalid ip version(s). should be 4, 6 or 46.'
|
||||||
|
exitp 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
[ "$IPVS" = 46 ] && IPVS="4 6"
|
[ "$IPVS" = 46 ] && IPVS="4 6"
|
||||||
|
|
||||||
configure_curl_opt
|
configure_curl_opt
|
||||||
|
|
||||||
ENABLE_HTTP=1
|
[ -n "$ENABLE_HTTP" ] || {
|
||||||
echo
|
ENABLE_HTTP=1
|
||||||
ask_yes_no_var ENABLE_HTTP "check http"
|
[ "$BATCH" = 1 ] || {
|
||||||
|
echo
|
||||||
ENABLE_HTTPS_TLS12=1
|
ask_yes_no_var ENABLE_HTTP "check http"
|
||||||
echo
|
}
|
||||||
ask_yes_no_var ENABLE_HTTPS_TLS12 "check https tls 1.2"
|
|
||||||
|
|
||||||
ENABLE_HTTPS_TLS13=0
|
|
||||||
echo
|
|
||||||
if [ -n "$TLS13" ]; then
|
|
||||||
echo "TLS 1.3 uses encrypted ServerHello. DPI cannot check domain name in server response."
|
|
||||||
echo "This can allow more bypass strategies to work."
|
|
||||||
echo "What works for TLS 1.2 will also work for TLS 1.3 but not vice versa."
|
|
||||||
echo "Most sites nowadays support TLS 1.3 but not all. If you can't find a strategy for TLS 1.2 use this test."
|
|
||||||
echo "TLS 1.3 only strategy is better than nothing."
|
|
||||||
ask_yes_no_var ENABLE_HTTPS_TLS13 "check https tls 1.3"
|
|
||||||
else
|
|
||||||
echo "installed curl version does not support TLS 1.3 . tests disabled."
|
|
||||||
fi
|
|
||||||
|
|
||||||
ENABLE_HTTP3=0
|
|
||||||
echo
|
|
||||||
if [ -n "$HTTP3" ]; then
|
|
||||||
echo "make sure target domain(s) support QUIC or result will be negative in any case"
|
|
||||||
ENABLE_HTTP3=1
|
|
||||||
ask_yes_no_var ENABLE_HTTP3 "check http3 QUIC"
|
|
||||||
else
|
|
||||||
echo "installed curl version does not support http3 QUIC. tests disabled."
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "sometimes ISPs use multiple DPIs or load balancing. bypass strategies may work unstable."
|
|
||||||
printf "how many times to repeat each test (default: 1) : "
|
|
||||||
read REPEATS
|
|
||||||
REPEATS=$((0+${REPEATS:-1}))
|
|
||||||
[ "$REPEATS" = 0 ] && {
|
|
||||||
echo invalid repeat count
|
|
||||||
exitp 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
echo
|
[ -n "$ENABLE_HTTPS_TLS12" ] || {
|
||||||
echo quick - scan as fast as possible to reveal any working strategy
|
ENABLE_HTTPS_TLS12=1
|
||||||
echo standard - do investigation what works on your DPI
|
[ "$BATCH" = 1 ] || {
|
||||||
echo force - scan maximum despite of result
|
echo
|
||||||
SCANLEVEL=${SCANLEVEL:-standard}
|
ask_yes_no_var ENABLE_HTTPS_TLS12 "check https tls 1.2"
|
||||||
ask_list SCANLEVEL "quick standard force" "$SCANLEVEL"
|
}
|
||||||
# disable tpws checks by default in quick mode
|
}
|
||||||
[ "$SCANLEVEL" = quick -a -z "$SKIP_TPWS" -a "$UNAME" != Darwin ] && SKIP_TPWS=1
|
|
||||||
|
[ -n "$ENABLE_HTTPS_TLS13" ] || {
|
||||||
|
ENABLE_HTTPS_TLS13=0
|
||||||
|
if [ -n "$TLS13" ]; then
|
||||||
|
[ "$BATCH" = 1 ] || {
|
||||||
|
echo
|
||||||
|
echo "TLS 1.3 uses encrypted ServerHello. DPI cannot check domain name in server response."
|
||||||
|
echo "This can allow more bypass strategies to work."
|
||||||
|
echo "What works for TLS 1.2 will also work for TLS 1.3 but not vice versa."
|
||||||
|
echo "Most sites nowadays support TLS 1.3 but not all. If you can't find a strategy for TLS 1.2 use this test."
|
||||||
|
echo "TLS 1.3 only strategy is better than nothing."
|
||||||
|
ask_yes_no_var ENABLE_HTTPS_TLS13 "check https tls 1.3"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
echo "installed curl version does not support TLS 1.3 . tests disabled."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -n "$ENABLE_HTTP3" ] || {
|
||||||
|
ENABLE_HTTP3=0
|
||||||
|
if [ -n "$HTTP3" ]; then
|
||||||
|
ENABLE_HTTP3=1
|
||||||
|
[ "$BATCH" = 1 ] || {
|
||||||
|
echo
|
||||||
|
echo "make sure target domain(s) support QUIC or result will be negative in any case"
|
||||||
|
ask_yes_no_var ENABLE_HTTP3 "check http3 QUIC"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
echo "installed curl version does not support http3 QUIC. tests disabled."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -n "$REPEATS" ] || {
|
||||||
|
[ "$BATCH" = 1 ] || {
|
||||||
|
echo
|
||||||
|
echo "sometimes ISPs use multiple DPIs or load balancing. bypass strategies may work unstable."
|
||||||
|
printf "how many times to repeat each test (default: 1) : "
|
||||||
|
read REPEATS
|
||||||
|
}
|
||||||
|
REPEATS=$((0+${REPEATS:-1}))
|
||||||
|
[ "$REPEATS" = 0 ] && {
|
||||||
|
echo invalid repeat count
|
||||||
|
exitp 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[ -z "$PARALLEL" -a $REPEATS -gt 1 ] && {
|
||||||
|
PARALLEL=0
|
||||||
|
[ "$BATCH" = 1 ] || {
|
||||||
|
echo
|
||||||
|
echo "parallel scan can greatly increase speed but may also trigger DDoS protection and cause false result"
|
||||||
|
ask_yes_no_var PARALLEL "enable parallel scan"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PARALLEL=${PARALLEL:-0}
|
||||||
|
|
||||||
|
[ -n "$SCANLEVEL" ] || {
|
||||||
|
SCANLEVEL=standard
|
||||||
|
[ "$BATCH" = 1 ] || {
|
||||||
|
echo
|
||||||
|
echo quick - scan as fast as possible to reveal any working strategy
|
||||||
|
echo standard - do investigation what works on your DPI
|
||||||
|
echo force - scan maximum despite of result
|
||||||
|
ask_list SCANLEVEL "quick standard force" "$SCANLEVEL"
|
||||||
|
# disable tpws checks by default in quick mode
|
||||||
|
[ "$SCANLEVEL" = quick -a -z "$SKIP_TPWS" -a "$UNAME" != Darwin ] && SKIP_TPWS=1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
|
||||||
@ -1976,14 +2074,15 @@ check_dns()
|
|||||||
unprepare_all()
|
unprepare_all()
|
||||||
{
|
{
|
||||||
# make sure we are not in a middle state that impacts connectivity
|
# make sure we are not in a middle state that impacts connectivity
|
||||||
rm -f "$HDRTEMP"
|
|
||||||
[ -n "$IPV" ] && {
|
|
||||||
pktws_ipt_unprepare_tcp 80
|
|
||||||
pktws_ipt_unprepare_tcp 443
|
|
||||||
pktws_ipt_unprepare_udp 443
|
|
||||||
}
|
|
||||||
ws_kill
|
ws_kill
|
||||||
|
wait
|
||||||
|
[ -n "$IPV" ] && {
|
||||||
|
pktws_ipt_unprepare_tcp $HTTP_PORT
|
||||||
|
pktws_ipt_unprepare_tcp $HTTPS_PORT
|
||||||
|
pktws_ipt_unprepare_udp $QUIC_PORT
|
||||||
|
}
|
||||||
cleanup
|
cleanup
|
||||||
|
rm -f "${HDRTEMP}"* "${PARALLEL_OUT}"*
|
||||||
}
|
}
|
||||||
sigint()
|
sigint()
|
||||||
{
|
{
|
||||||
@ -2029,10 +2128,10 @@ for dom in $DOMAINS; do
|
|||||||
for IPV in $IPVS; do
|
for IPV in $IPVS; do
|
||||||
configure_ip_version
|
configure_ip_version
|
||||||
[ "$ENABLE_HTTP" = 1 ] && {
|
[ "$ENABLE_HTTP" = 1 ] && {
|
||||||
check_domain_port_block $dom $HTTP_PORT
|
[ "$SKIP_IPBLOCK" = 1 ] || check_domain_port_block $dom $HTTP_PORT
|
||||||
check_domain_http $dom
|
check_domain_http $dom
|
||||||
}
|
}
|
||||||
[ "$ENABLE_HTTPS_TLS12" = 1 -o "$ENABLE_HTTPS_TLS13" = 1 ] && check_domain_port_block $dom $HTTPS_PORT
|
[ "$ENABLE_HTTPS_TLS12" = 1 -o "$ENABLE_HTTPS_TLS13" = 1 ] && [ "$SKIP_IPBLOCK" != 1 ] && check_domain_port_block $dom $HTTPS_PORT
|
||||||
[ "$ENABLE_HTTPS_TLS12" = 1 ] && check_domain_https_tls12 $dom
|
[ "$ENABLE_HTTPS_TLS12" = 1 ] && check_domain_https_tls12 $dom
|
||||||
[ "$ENABLE_HTTPS_TLS13" = 1 ] && check_domain_https_tls13 $dom
|
[ "$ENABLE_HTTPS_TLS13" = 1 ] && check_domain_https_tls13 $dom
|
||||||
[ "$ENABLE_HTTP3" = 1 ] && check_domain_http3 $dom
|
[ "$ENABLE_HTTP3" = 1 ] && check_domain_http3 $dom
|
||||||
|
@ -241,7 +241,7 @@ fix_sbin_path()
|
|||||||
# it can calculate floating point expr
|
# it can calculate floating point expr
|
||||||
calc()
|
calc()
|
||||||
{
|
{
|
||||||
awk "BEGIN { print $*}";
|
LC_ALL=C awk "BEGIN { print $*}";
|
||||||
}
|
}
|
||||||
|
|
||||||
fsleep_setup()
|
fsleep_setup()
|
||||||
@ -318,18 +318,27 @@ setup_md5()
|
|||||||
exists $MD5 || MD5=md5
|
exists $MD5 || MD5=md5
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setup_random()
|
||||||
|
{
|
||||||
|
[ -n "$RCUT" ] && return
|
||||||
|
RCUT="cut -c 1-17"
|
||||||
|
# some shells can operate with 32 bit signed int
|
||||||
|
[ $((0x100000000)) = 0 ] && RCUT="cut -c 1-9"
|
||||||
|
}
|
||||||
|
|
||||||
random()
|
random()
|
||||||
{
|
{
|
||||||
# $1 - min, $2 - max
|
# $1 - min, $2 - max
|
||||||
local r rs
|
local r rs
|
||||||
setup_md5
|
setup_md5
|
||||||
|
setup_random
|
||||||
if [ -c /dev/urandom ]; then
|
if [ -c /dev/urandom ]; then
|
||||||
read rs </dev/urandom
|
read rs </dev/urandom
|
||||||
else
|
else
|
||||||
rs="$RANDOM$RANDOM$(date)"
|
rs="$RANDOM$RANDOM$(date)"
|
||||||
fi
|
fi
|
||||||
# shells use signed int64
|
# shells use signed int64
|
||||||
r=1$(echo $rs | $MD5 | sed 's/[^0-9]//g' | cut -c 1-17)
|
r=1$(echo $rs | $MD5 | sed 's/[^0-9]//g' | $RCUT)
|
||||||
echo $(( ($r % ($2-$1+1)) + $1 ))
|
echo $(( ($r % ($2-$1+1)) + $1 ))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@ custom_runner()
|
|||||||
# $1 - function name
|
# $1 - function name
|
||||||
# $2+ - params
|
# $2+ - params
|
||||||
|
|
||||||
|
[ "$DISABLE_CUSTOM" = 1 ] && return 0
|
||||||
|
|
||||||
local n script FUNC=$1
|
local n script FUNC=$1
|
||||||
|
|
||||||
shift
|
shift
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
readonly GET_LIST_PREFIX=/ipset/get_
|
GET_LIST_PREFIX=/ipset/get_
|
||||||
|
|
||||||
SYSTEMD_DIR=/lib/systemd
|
SYSTEMD_DIR=/lib/systemd
|
||||||
[ -d "$SYSTEMD_DIR" ] || SYSTEMD_DIR=/usr/lib/systemd
|
[ -d "$SYSTEMD_DIR" ] || SYSTEMD_DIR=/usr/lib/systemd
|
||||||
@ -140,7 +140,7 @@ echo_var()
|
|||||||
eval v="\$$1"
|
eval v="\$$1"
|
||||||
if find_str_in_list $1 "$EDITVAR_NEWLINE_VARS"; then
|
if find_str_in_list $1 "$EDITVAR_NEWLINE_VARS"; then
|
||||||
echo "$1=\""
|
echo "$1=\""
|
||||||
echo "$v\"" | sed "s/$EDITVAR_NEWLINE_DELIMETER /$EDITVAR_NEWLINE_DELIMETER\n/g"
|
echo "$v\"" | tr '\n' ' ' | tr -d '\r' | sed -e 's/^ *//' -e 's/ *$//' -e "s/$EDITVAR_NEWLINE_DELIMETER /$EDITVAR_NEWLINE_DELIMETER\n/g"
|
||||||
else
|
else
|
||||||
if contains "$v" " "; then
|
if contains "$v" " "; then
|
||||||
echo $1=\"$v\"
|
echo $1=\"$v\"
|
||||||
@ -170,6 +170,7 @@ list_vars()
|
|||||||
echo_var $1
|
echo_var $1
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
echo
|
||||||
}
|
}
|
||||||
|
|
||||||
openrc_test()
|
openrc_test()
|
||||||
@ -616,11 +617,17 @@ write_config_var()
|
|||||||
replace_var_def $1 "$M" "$ZAPRET_CONFIG"
|
replace_var_def $1 "$M" "$ZAPRET_CONFIG"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
no_prereq_exit()
|
||||||
|
{
|
||||||
|
echo could not install prerequisites
|
||||||
|
exitp 6
|
||||||
|
}
|
||||||
check_prerequisites_linux()
|
check_prerequisites_linux()
|
||||||
{
|
{
|
||||||
echo \* checking prerequisites
|
echo \* checking prerequisites
|
||||||
|
|
||||||
local s cmd PKGS UTILS req="curl curl"
|
local s cmd PKGS UTILS req="curl curl"
|
||||||
|
local APTGET DNF YUM PACMAN ZYPPER EOPKG APK
|
||||||
case "$FWTYPE" in
|
case "$FWTYPE" in
|
||||||
iptables)
|
iptables)
|
||||||
req="$req iptables iptables ip6tables iptables ipset ipset"
|
req="$req iptables iptables ip6tables iptables ipset ipset"
|
||||||
@ -649,6 +656,7 @@ check_prerequisites_linux()
|
|||||||
echo packages required : $PKGS
|
echo packages required : $PKGS
|
||||||
|
|
||||||
APTGET=$(whichq apt-get)
|
APTGET=$(whichq apt-get)
|
||||||
|
DNF=$(whichq dnf)
|
||||||
YUM=$(whichq yum)
|
YUM=$(whichq yum)
|
||||||
PACMAN=$(whichq pacman)
|
PACMAN=$(whichq pacman)
|
||||||
ZYPPER=$(whichq zypper)
|
ZYPPER=$(whichq zypper)
|
||||||
@ -656,39 +664,23 @@ check_prerequisites_linux()
|
|||||||
APK=$(whichq apk)
|
APK=$(whichq apk)
|
||||||
if [ -x "$APTGET" ] ; then
|
if [ -x "$APTGET" ] ; then
|
||||||
"$APTGET" update
|
"$APTGET" update
|
||||||
"$APTGET" install -y --no-install-recommends $PKGS dnsutils || {
|
"$APTGET" install -y --no-install-recommends $PKGS dnsutils || no_prereq_exit
|
||||||
echo could not install prerequisites
|
elif [ -x "$DNF" ] ; then
|
||||||
exitp 6
|
"$DNF" -y install $PKGS || no_prereq_exit
|
||||||
}
|
|
||||||
elif [ -x "$YUM" ] ; then
|
elif [ -x "$YUM" ] ; then
|
||||||
"$YUM" -y install $PKGS || {
|
"$YUM" -y install $PKGS || no_prereq_exit
|
||||||
echo could not install prerequisites
|
|
||||||
exitp 6
|
|
||||||
}
|
|
||||||
elif [ -x "$PACMAN" ] ; then
|
elif [ -x "$PACMAN" ] ; then
|
||||||
"$PACMAN" -Syy
|
"$PACMAN" -Syy
|
||||||
"$PACMAN" --noconfirm -S $PKGS || {
|
"$PACMAN" --noconfirm -S $PKGS || no_prereq_exit
|
||||||
echo could not install prerequisites
|
|
||||||
exitp 6
|
|
||||||
}
|
|
||||||
elif [ -x "$ZYPPER" ] ; then
|
elif [ -x "$ZYPPER" ] ; then
|
||||||
"$ZYPPER" --non-interactive install $PKGS || {
|
"$ZYPPER" --non-interactive install $PKGS || no_prereq_exit
|
||||||
echo could not install prerequisites
|
|
||||||
exitp 6
|
|
||||||
}
|
|
||||||
elif [ -x "$EOPKG" ] ; then
|
elif [ -x "$EOPKG" ] ; then
|
||||||
"$EOPKG" -y install $PKGS || {
|
"$EOPKG" -y install $PKGS || no_prereq_exit
|
||||||
echo could not install prerequisites
|
|
||||||
exitp 6
|
|
||||||
}
|
|
||||||
elif [ -x "$APK" ] ; then
|
elif [ -x "$APK" ] ; then
|
||||||
"$APK" update
|
"$APK" update
|
||||||
# for alpine
|
# for alpine
|
||||||
[ "$FWTYPE" = iptables ] && [ -n "$($APK list ip6tables)" ] && PKGS="$PKGS ip6tables"
|
[ "$FWTYPE" = iptables ] && [ -n "$($APK list ip6tables)" ] && PKGS="$PKGS ip6tables"
|
||||||
"$APK" add $PKGS || {
|
"$APK" add $PKGS || no_prereq_exit
|
||||||
echo could not install prerequisites
|
|
||||||
exitp 6
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
echo supported package manager not found
|
echo supported package manager not found
|
||||||
echo you must manually install : $UTILS
|
echo you must manually install : $UTILS
|
||||||
@ -837,3 +829,37 @@ select_fwtype()
|
|||||||
echo select firewall type :
|
echo select firewall type :
|
||||||
ask_list FWTYPE "iptables nftables" "$FWTYPE" && write_config_var FWTYPE
|
ask_list FWTYPE "iptables nftables" "$FWTYPE" && write_config_var FWTYPE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dry_run_tpws_()
|
||||||
|
{
|
||||||
|
local TPWS="$ZAPRET_BASE/tpws/tpws"
|
||||||
|
echo verifying tpws options
|
||||||
|
"$TPWS" --dry-run "$@"
|
||||||
|
}
|
||||||
|
dry_run_nfqws_()
|
||||||
|
{
|
||||||
|
local NFQWS="$ZAPRET_BASE/nfq/nfqws"
|
||||||
|
echo verifying nfqws options
|
||||||
|
"$NFQWS" --dry-run "$@"
|
||||||
|
}
|
||||||
|
dry_run_tpws()
|
||||||
|
{
|
||||||
|
[ "$TPWS_ENABLE" = 1 ] || return 0
|
||||||
|
local opt="$TPWS_OPT" port=${TPPORT_SOCKS:-988}
|
||||||
|
filter_apply_hostlist_target opt
|
||||||
|
dry_run_tpws_ --port=$port $opt
|
||||||
|
}
|
||||||
|
dry_run_tpws_socks()
|
||||||
|
{
|
||||||
|
[ "$TPWS_SOCKS_ENABLE" = 1 ] || return 0
|
||||||
|
local opt="$TPWS_SOCKS_OPT" port=${TPPORT:-987}
|
||||||
|
filter_apply_hostlist_target opt
|
||||||
|
dry_run_tpws_ --port=$port --socks $opt
|
||||||
|
}
|
||||||
|
dry_run_nfqws()
|
||||||
|
{
|
||||||
|
[ "$NFQWS_ENABLE" = 1 ] || return 0
|
||||||
|
local opt="$NFQWS_OPT" qn=${QNUM:-200}
|
||||||
|
filter_apply_hostlist_target opt
|
||||||
|
dry_run_nfqws_ --qnum=$qn $opt
|
||||||
|
}
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
std_ports
|
std_ports
|
||||||
readonly ipt_connbytes="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes"
|
ipt_connbytes="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes"
|
||||||
|
IPSET_EXCLUDE="-m set ! --match-set nozapret"
|
||||||
|
IPSET_EXCLUDE6="-m set ! --match-set nozapret6"
|
||||||
|
IPBAN_EXCLUDE="-m set ! --match-set ipban"
|
||||||
|
IPBAN_EXCLUDE6="-m set ! --match-set ipban6"
|
||||||
|
|
||||||
ipt()
|
ipt()
|
||||||
{
|
{
|
||||||
@ -132,7 +136,7 @@ _fw_tpws4()
|
|||||||
|
|
||||||
ipt_print_op $1 "$2" "tpws (port $3)"
|
ipt_print_op $1 "$2" "tpws (port $3)"
|
||||||
|
|
||||||
rule="$2 $IPSET_EXCLUDE dst -j DNAT --to $TPWS_LOCALHOST4:$3"
|
rule="$2 $IPSET_EXCLUDE dst $IPBAN_EXCLUDE dst -j DNAT --to $TPWS_LOCALHOST4:$3"
|
||||||
for i in $4 ; do
|
for i in $4 ; do
|
||||||
ipt_add_del $1 PREROUTING -t nat -i $i $rule
|
ipt_add_del $1 PREROUTING -t nat -i $i $rule
|
||||||
done
|
done
|
||||||
@ -160,7 +164,7 @@ _fw_tpws6()
|
|||||||
|
|
||||||
ipt_print_op $1 "$2" "tpws (port $3)" 6
|
ipt_print_op $1 "$2" "tpws (port $3)" 6
|
||||||
|
|
||||||
rule="$2 $IPSET_EXCLUDE6 dst"
|
rule="$2 $IPSET_EXCLUDE6 dst $IPBAN_EXCLUDE6 dst"
|
||||||
for i in $4 ; do
|
for i in $4 ; do
|
||||||
_dnat6_target $i DNAT6
|
_dnat6_target $i DNAT6
|
||||||
[ -n "$DNAT6" -a "$DNAT6" != "-" ] && ipt6_add_del $1 PREROUTING -t nat -i $i $rule -j DNAT --to [$DNAT6]:$3
|
[ -n "$DNAT6" -a "$DNAT6" != "-" ] && ipt6_add_del $1 PREROUTING -t nat -i $i $rule -j DNAT --to [$DNAT6]:$3
|
||||||
@ -349,27 +353,37 @@ ipt_do_nfqws_in_out()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
zapret_do_firewall_standard_rules_ipt()
|
zapret_do_firewall_standard_tpws_rules_ipt()
|
||||||
{
|
{
|
||||||
# $1 - 1 - add, 0 - del
|
# $1 - 1 - add, 0 - del
|
||||||
|
|
||||||
local f4 f6
|
local f4 f6
|
||||||
|
|
||||||
[ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] &&
|
[ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] && {
|
||||||
{
|
|
||||||
f4="-p tcp -m multiport --dports $TPWS_PORTS_IPT"
|
f4="-p tcp -m multiport --dports $TPWS_PORTS_IPT"
|
||||||
f6=$f4
|
f6=$f4
|
||||||
filter_apply_ipset_target f4 f6
|
filter_apply_ipset_target f4 f6
|
||||||
fw_tpws $1 "$f4" "$f6" $TPPORT
|
fw_tpws $1 "$f4" "$f6" $TPPORT
|
||||||
}
|
}
|
||||||
[ "$NFQWS_ENABLE" = 1 ] &&
|
}
|
||||||
{
|
zapret_do_firewall_standard_nfqws_rules_ipt()
|
||||||
|
{
|
||||||
|
# $1 - 1 - add, 0 - del
|
||||||
|
|
||||||
|
[ "$NFQWS_ENABLE" = 1 ] && {
|
||||||
ipt_do_nfqws_in_out $1 tcp "$NFQWS_PORTS_TCP_IPT" "$NFQWS_TCP_PKT_OUT" "$NFQWS_TCP_PKT_IN"
|
ipt_do_nfqws_in_out $1 tcp "$NFQWS_PORTS_TCP_IPT" "$NFQWS_TCP_PKT_OUT" "$NFQWS_TCP_PKT_IN"
|
||||||
ipt_do_nfqws_in_out $1 tcp "$NFQWS_PORTS_TCP_KEEPALIVE_IPT" keepalive "$NFQWS_TCP_PKT_IN"
|
ipt_do_nfqws_in_out $1 tcp "$NFQWS_PORTS_TCP_KEEPALIVE_IPT" keepalive "$NFQWS_TCP_PKT_IN"
|
||||||
ipt_do_nfqws_in_out $1 udp "$NFQWS_PORTS_UDP_IPT" "$NFQWS_UDP_PKT_OUT" "$NFQWS_UDP_PKT_IN"
|
ipt_do_nfqws_in_out $1 udp "$NFQWS_PORTS_UDP_IPT" "$NFQWS_UDP_PKT_OUT" "$NFQWS_UDP_PKT_IN"
|
||||||
ipt_do_nfqws_in_out $1 udp "$NFQWS_PORTS_UDP_KEEPALIVE_IPT" keepalive "$NFQWS_UDP_PKT_IN"
|
ipt_do_nfqws_in_out $1 udp "$NFQWS_PORTS_UDP_KEEPALIVE_IPT" keepalive "$NFQWS_UDP_PKT_IN"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
zapret_do_firewall_standard_rules_ipt()
|
||||||
|
{
|
||||||
|
# $1 - 1 - add, 0 - del
|
||||||
|
|
||||||
|
zapret_do_firewall_standard_tpws_rules_ipt $1
|
||||||
|
zapret_do_firewall_standard_nfqws_rules_ipt $1
|
||||||
|
}
|
||||||
|
|
||||||
zapret_do_firewall_rules_ipt()
|
zapret_do_firewall_rules_ipt()
|
||||||
{
|
{
|
||||||
|
55
common/linux_daemons.sh
Normal file
55
common/linux_daemons.sh
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
standard_mode_tpws_socks()
|
||||||
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
local opt
|
||||||
|
[ "$TPWS_SOCKS_ENABLE" = 1 ] && {
|
||||||
|
opt="--port=$TPPORT_SOCKS $TPWS_SOCKS_OPT"
|
||||||
|
filter_apply_hostlist_target opt
|
||||||
|
do_tpws_socks $1 2 "$opt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
standard_mode_tpws()
|
||||||
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
local opt
|
||||||
|
[ "$TPWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$TPWS_OPT" && {
|
||||||
|
opt="--port=$TPPORT $TPWS_OPT"
|
||||||
|
filter_apply_hostlist_target opt
|
||||||
|
do_tpws $1 1 "$opt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
standard_mode_nfqws()
|
||||||
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
local opt
|
||||||
|
[ "$NFQWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$NFQWS_OPT" && {
|
||||||
|
opt="--qnum=$QNUM $NFQWS_OPT"
|
||||||
|
filter_apply_hostlist_target opt
|
||||||
|
do_nfqws $1 3 "$opt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
standard_mode_daemons()
|
||||||
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
|
standard_mode_tpws_socks $1
|
||||||
|
standard_mode_tpws $1
|
||||||
|
standard_mode_nfqws $1
|
||||||
|
}
|
||||||
|
zapret_do_daemons()
|
||||||
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
|
standard_mode_daemons $1
|
||||||
|
custom_runner zapret_custom_daemons $1
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
zapret_run_daemons()
|
||||||
|
{
|
||||||
|
zapret_do_daemons 1 "$@"
|
||||||
|
}
|
||||||
|
zapret_stop_daemons()
|
||||||
|
{
|
||||||
|
zapret_do_daemons 0 "$@"
|
||||||
|
}
|
@ -4,6 +4,8 @@
|
|||||||
# PREROUTING - can't DNAT to ::1. can DNAT to link local of -i interface or to any global addr
|
# PREROUTING - can't DNAT to ::1. can DNAT to link local of -i interface or to any global addr
|
||||||
# not a good idea to expose tpws to the world (bind to ::)
|
# not a good idea to expose tpws to the world (bind to ::)
|
||||||
|
|
||||||
|
# max wait time for the link local ipv6 on the LAN interface
|
||||||
|
LINKLOCAL_WAIT_SEC=${LINKLOCAL_WAIT_SEC:-5}
|
||||||
|
|
||||||
get_ipv6_linklocal()
|
get_ipv6_linklocal()
|
||||||
{
|
{
|
||||||
@ -125,3 +127,13 @@ resolve_lower_devices()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default_route_interfaces6()
|
||||||
|
{
|
||||||
|
sed -nre 's/^00000000000000000000000000000000 00 [0-9a-f]{32} [0-9a-f]{2} [0-9a-f]{32} [0-9a-f]{8} [0-9a-f]{8} [0-9a-f]{8} [0-9a-f]{8} +(.*)$/\1/p' /proc/net/ipv6_route | grep -v '^lo$' | sort -u | xargs
|
||||||
|
}
|
||||||
|
|
||||||
|
default_route_interfaces4()
|
||||||
|
{
|
||||||
|
sed -nre 's/^([^\t]+)\t00000000\t[0-9A-F]{8}\t[0-9A-F]{4}\t[0-9]+\t[0-9]+\t[0-9]+\t00000000.*$/\1/p' /proc/net/route | sort -u | xargs
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
readonly HOSTLIST_MARKER="<HOSTLIST>"
|
HOSTLIST_MARKER="<HOSTLIST>"
|
||||||
readonly HOSTLIST_NOAUTO_MARKER="<HOSTLIST_NOAUTO>"
|
HOSTLIST_NOAUTO_MARKER="<HOSTLIST_NOAUTO>"
|
||||||
|
|
||||||
find_hostlists()
|
find_hostlists()
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[ -n "$ZAPRET_NFT_TABLE" ] || ZAPRET_NFT_TABLE=zapret
|
[ -n "$ZAPRET_NFT_TABLE" ] || ZAPRET_NFT_TABLE=zapret
|
||||||
readonly nft_connbytes="ct original packets"
|
nft_connbytes="ct original packets"
|
||||||
|
|
||||||
# required for : nft -f -
|
# required for : nft -f -
|
||||||
create_dev_stdin
|
create_dev_stdin
|
||||||
@ -263,28 +263,6 @@ nft_add_flow_offload_exemption()
|
|||||||
[ "$DISABLE_IPV6" = "1" -o -z "$2" ] || nft_add_rule flow_offload oifname @wanif6 $2 ip6 daddr != @nozapret6 return comment \"$3\"
|
[ "$DISABLE_IPV6" = "1" -o -z "$2" ] || nft_add_rule flow_offload oifname @wanif6 $2 ip6 daddr != @nozapret6 return comment \"$3\"
|
||||||
}
|
}
|
||||||
|
|
||||||
nft_hw_offload_supported()
|
|
||||||
{
|
|
||||||
# $1,$2,... - interface names
|
|
||||||
local devices res=1
|
|
||||||
make_quoted_comma_list devices "$@"
|
|
||||||
[ -n "$devices" ] && devices="devices={$devices};"
|
|
||||||
nft add table ${ZAPRET_NFT_TABLE}_test && nft add flowtable ${ZAPRET_NFT_TABLE}_test ft "{ flags offload; $devices }" 2>/dev/null && res=0
|
|
||||||
nft delete table ${ZAPRET_NFT_TABLE}_test 2>/dev/null
|
|
||||||
return $res
|
|
||||||
}
|
|
||||||
|
|
||||||
nft_hw_offload_find_supported()
|
|
||||||
{
|
|
||||||
# $1,$2,... - interface names
|
|
||||||
local supported_list
|
|
||||||
while [ -n "$1" ]; do
|
|
||||||
nft_hw_offload_supported "$1" && append_separator_list supported_list ' ' '' "$1"
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
echo $supported_list
|
|
||||||
}
|
|
||||||
|
|
||||||
nft_apply_flow_offloading()
|
nft_apply_flow_offloading()
|
||||||
{
|
{
|
||||||
# ft can be absent
|
# ft can be absent
|
||||||
@ -370,17 +348,15 @@ flush set inet $ZAPRET_NFT_TABLE lanif"
|
|||||||
nft_create_or_update_flowtable 'offload' 2>/dev/null
|
nft_create_or_update_flowtable 'offload' 2>/dev/null
|
||||||
# then add elements. some of them can cause error because unsupported
|
# then add elements. some of them can cause error because unsupported
|
||||||
for i in $ALLDEVS; do
|
for i in $ALLDEVS; do
|
||||||
if nft_hw_offload_supported $i; then
|
# first try to add interface itself
|
||||||
nft_create_or_update_flowtable 'offload' $i
|
nft_create_or_update_flowtable 'offload' $i 2>/dev/null
|
||||||
else
|
# bridge members must be added instead of the bridge itself
|
||||||
# bridge members must be added instead of the bridge itself
|
# some members may not support hw offload. example : lan1 lan2 lan3 support, wlan0 wlan1 - not
|
||||||
# some members may not support hw offload. example : lan1 lan2 lan3 support, wlan0 wlan1 - not
|
devs=$(resolve_lower_devices $i)
|
||||||
devs=$(resolve_lower_devices $i)
|
for j in $devs; do
|
||||||
for j in $devs; do
|
# do not display error if addition failed
|
||||||
# do not display error if addition failed
|
nft_create_or_update_flowtable 'offload' $j 2>/dev/null
|
||||||
nft_create_or_update_flowtable 'offload' $j 2>/dev/null
|
done
|
||||||
done
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@ -411,8 +387,8 @@ _nft_fw_tpws4()
|
|||||||
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
|
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
|
||||||
local filter="$1" port="$2"
|
local filter="$1" port="$2"
|
||||||
nft_print_op "$filter" "tpws (port $2)" 4
|
nft_print_op "$filter" "tpws (port $2)" 4
|
||||||
nft_insert_rule dnat_output skuid != $WS_USER ${3:+oifname @wanif }$filter ip daddr != @nozapret $FW_EXTRA_POST dnat ip to $TPWS_LOCALHOST4:$port
|
nft_insert_rule dnat_output skuid != $WS_USER ${3:+oifname @wanif }$filter ip daddr != @nozapret ip daddr != @ipban $FW_EXTRA_POST dnat ip to $TPWS_LOCALHOST4:$port
|
||||||
nft_insert_rule dnat_pre iifname @lanif $filter ip daddr != @nozapret $FW_EXTRA_POST dnat ip to $TPWS_LOCALHOST4:$port
|
nft_insert_rule dnat_pre iifname @lanif $filter ip daddr != @nozapret ip daddr != @ipban $FW_EXTRA_POST dnat ip to $TPWS_LOCALHOST4:$port
|
||||||
prepare_route_localnet
|
prepare_route_localnet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -426,9 +402,9 @@ _nft_fw_tpws6()
|
|||||||
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
|
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
|
||||||
local filter="$1" port="$2" DNAT6 i
|
local filter="$1" port="$2" DNAT6 i
|
||||||
nft_print_op "$filter" "tpws (port $port)" 6
|
nft_print_op "$filter" "tpws (port $port)" 6
|
||||||
nft_insert_rule dnat_output skuid != $WS_USER ${4:+oifname @wanif6 }$filter ip6 daddr != @nozapret6 $FW_EXTRA_POST dnat ip6 to [::1]:$port
|
nft_insert_rule dnat_output skuid != $WS_USER ${4:+oifname @wanif6 }$filter ip6 daddr != @nozapret6 ip6 daddr != @ipban6 $FW_EXTRA_POST dnat ip6 to [::1]:$port
|
||||||
[ -n "$3" ] && {
|
[ -n "$3" ] && {
|
||||||
nft_insert_rule dnat_pre $filter ip6 daddr != @nozapret6 $FW_EXTRA_POST dnat ip6 to iifname map @link_local:$port
|
nft_insert_rule dnat_pre $filter ip6 daddr != @nozapret6 ip6 daddr != @ipban6 $FW_EXTRA_POST dnat ip6 to iifname map @link_local:$port
|
||||||
for i in $3; do
|
for i in $3; do
|
||||||
_dnat6_target $i DNAT6
|
_dnat6_target $i DNAT6
|
||||||
# can be multiple tpws processes on different ports
|
# can be multiple tpws processes on different ports
|
||||||
@ -640,25 +616,31 @@ nft_apply_nfqws_in_out()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
zapret_apply_firewall_standard_rules_nft()
|
zapret_apply_firewall_standard_tpws_rules_nft()
|
||||||
{
|
{
|
||||||
local f4 f6
|
local f4 f6
|
||||||
|
|
||||||
[ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] &&
|
[ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] && {
|
||||||
{
|
|
||||||
f4="tcp dport {$TPWS_PORTS}"
|
f4="tcp dport {$TPWS_PORTS}"
|
||||||
f6=$f4
|
f6=$f4
|
||||||
nft_filter_apply_ipset_target f4 f6
|
nft_filter_apply_ipset_target f4 f6
|
||||||
nft_fw_tpws "$f4" "$f6" $TPPORT
|
nft_fw_tpws "$f4" "$f6" $TPPORT
|
||||||
}
|
}
|
||||||
[ "$NFQWS_ENABLE" = 1 ] &&
|
}
|
||||||
{
|
zapret_apply_firewall_standard_nfqws_rules_nft()
|
||||||
|
{
|
||||||
|
[ "$NFQWS_ENABLE" = 1 ] && {
|
||||||
nft_apply_nfqws_in_out tcp "$NFQWS_PORTS_TCP" "$NFQWS_TCP_PKT_OUT" "$NFQWS_TCP_PKT_IN"
|
nft_apply_nfqws_in_out tcp "$NFQWS_PORTS_TCP" "$NFQWS_TCP_PKT_OUT" "$NFQWS_TCP_PKT_IN"
|
||||||
nft_apply_nfqws_in_out tcp "$NFQWS_PORTS_TCP_KEEPALIVE" keepalive "$NFQWS_TCP_PKT_IN"
|
nft_apply_nfqws_in_out tcp "$NFQWS_PORTS_TCP_KEEPALIVE" keepalive "$NFQWS_TCP_PKT_IN"
|
||||||
nft_apply_nfqws_in_out udp "$NFQWS_PORTS_UDP" "$NFQWS_UDP_PKT_OUT" "$NFQWS_UDP_PKT_IN"
|
nft_apply_nfqws_in_out udp "$NFQWS_PORTS_UDP" "$NFQWS_UDP_PKT_OUT" "$NFQWS_UDP_PKT_IN"
|
||||||
nft_apply_nfqws_in_out udp "$NFQWS_PORTS_UDP_KEEPALIVE" keepalive "$NFQWS_UDP_PKT_IN"
|
nft_apply_nfqws_in_out udp "$NFQWS_PORTS_UDP_KEEPALIVE" keepalive "$NFQWS_UDP_PKT_IN"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
zapret_apply_firewall_standard_rules_nft()
|
||||||
|
{
|
||||||
|
zapret_apply_firewall_standard_tpws_rules_nft
|
||||||
|
zapret_apply_firewall_standard_nfqws_rules_nft
|
||||||
|
}
|
||||||
|
|
||||||
zapret_apply_firewall_rules_nft()
|
zapret_apply_firewall_rules_nft()
|
||||||
{
|
{
|
||||||
|
@ -97,7 +97,7 @@ NFQWS_OPT="
|
|||||||
# none,ipset,hostlist,autohostlist
|
# none,ipset,hostlist,autohostlist
|
||||||
MODE_FILTER=none
|
MODE_FILTER=none
|
||||||
|
|
||||||
# openwrt only : donttouch,none,software,hardware
|
# donttouch,none,software,hardware
|
||||||
FLOWOFFLOAD=donttouch
|
FLOWOFFLOAD=donttouch
|
||||||
|
|
||||||
# openwrt: specify networks to be treated as LAN. default is "lan"
|
# openwrt: specify networks to be treated as LAN. default is "lan"
|
||||||
|
@ -389,3 +389,99 @@ blockcheck: added CURL_OPT
|
|||||||
blockcheck: new strategies support
|
blockcheck: new strategies support
|
||||||
blockcheck: test sequence rework
|
blockcheck: test sequence rework
|
||||||
blockcheck: view all working strategies in summary
|
blockcheck: view all working strategies in summary
|
||||||
|
|
||||||
|
v69.1:
|
||||||
|
|
||||||
|
init.d: keenetic udp fix custom
|
||||||
|
tpws: fixed incorrect hostlist checks
|
||||||
|
|
||||||
|
v69.2:
|
||||||
|
|
||||||
|
nfqws,tpws: --skip
|
||||||
|
nfqws: --methodeol
|
||||||
|
init.d: do not use pgrep in sysv for busybox compat
|
||||||
|
|
||||||
|
v69.3
|
||||||
|
|
||||||
|
nfqws,tpws: fixed ipsets and hostlists
|
||||||
|
all progs: version numbers for github, build date/time for self built
|
||||||
|
repo: light release for openwrt and embedded systems
|
||||||
|
repo: sha256sum
|
||||||
|
|
||||||
|
v69.4
|
||||||
|
|
||||||
|
nfqws: fakedsplit/fakeddisorder fakes for both split segments
|
||||||
|
nfqws: --dpi-desync-fakedsplit-pattern
|
||||||
|
|
||||||
|
v69.5
|
||||||
|
|
||||||
|
nfqws,tpws: --dry-run
|
||||||
|
install_easy: check tpws and nfqws options validity
|
||||||
|
|
||||||
|
v69.6
|
||||||
|
|
||||||
|
nfqws: set NETLINK_NO_ENOBUFS to fix possible nfq recv errors
|
||||||
|
init.d: unify custom scripts for linux
|
||||||
|
init.d: new custom scripts : 20-fw-extra, 50-wg4all
|
||||||
|
|
||||||
|
v69.7
|
||||||
|
|
||||||
|
nfqws,tpws: --comment
|
||||||
|
nfqws: trash flood warning
|
||||||
|
winws: exclude empty outgoing ack packets in windivert filter
|
||||||
|
|
||||||
|
v69.8
|
||||||
|
|
||||||
|
winws: accept empty outgoing RST and FIN packets for conntrack needs
|
||||||
|
repo: lexra build
|
||||||
|
|
||||||
|
v69.9
|
||||||
|
|
||||||
|
init.d: exclude ipban from tpws redirection
|
||||||
|
macos: fix install_easy
|
||||||
|
macos: fix national decimal separator in sleep
|
||||||
|
ipset: scripts maintenance
|
||||||
|
|
||||||
|
v70
|
||||||
|
|
||||||
|
blockcheck: override all dialog questions and enable batch mode
|
||||||
|
blockcheck: parallel attempts
|
||||||
|
nfqws: weaken wireguard initiation recognition. use len=148 and data[0]=1 signature
|
||||||
|
nfqws: apply split+seqovl only to the first reasm fragment
|
||||||
|
install_easy: dnf packager support
|
||||||
|
nfqws,tpws: hostlist/ipset track not only file mod time but also file size
|
||||||
|
nfqws,tpws,ipset: return lists reload on HUP
|
||||||
|
nfqws,blockcheck: --dpi-desync-fake-tls-mod
|
||||||
|
|
||||||
|
v70.1
|
||||||
|
|
||||||
|
nfqws: --dpi-desync-fake-tls-mod=dupsid
|
||||||
|
nfqws,tpws: test accessibility of list files after privs drop
|
||||||
|
nfqws,tpws: --version
|
||||||
|
|
||||||
|
v70.4
|
||||||
|
|
||||||
|
nfqws,tpws: ^ prefix in hostlist to disable subdomain matches
|
||||||
|
nfqws,tpws: optional systemd notify support. compile using 'make systemd'
|
||||||
|
nfqws,tpws: systemd instance templates for nfqws and tpws
|
||||||
|
nfqws,tpws: separate droproot from dropcaps
|
||||||
|
tpws: detect WSL 1 and warn about non-working options
|
||||||
|
|
||||||
|
v70.5
|
||||||
|
|
||||||
|
nfqws: multiple --dpi-desync-fake-xxx
|
||||||
|
nfqws: support of inter-packet fragmented QUIC CRYPTO
|
||||||
|
|
||||||
|
v70.6
|
||||||
|
|
||||||
|
nfqws: detect Discord Voice IP discovery packets
|
||||||
|
nfqws: detect STUN message packets
|
||||||
|
nfqws: change SNI to specified value tls mod : --dpi-desync-fake-tls-mod sni=<sni>
|
||||||
|
nfqws: update default TLS ClientHello fake. firefox 136.0.4 finger, no kyber, SNI=microsoft.com
|
||||||
|
nfqws: multiple mods for multiple TLS fakes
|
||||||
|
init.d: remove 50-discord
|
||||||
|
blockcheck: use tpws --fix-seg on linux for multiple splits
|
||||||
|
|
||||||
|
v70.7
|
||||||
|
|
||||||
|
nfqws,tpws: debug tls version, alpn, ech
|
||||||
|
@ -12,10 +12,10 @@ Other packages may be required on your distribution. Look for the errors.
|
|||||||
|
|
||||||
examples :
|
examples :
|
||||||
|
|
||||||
curl -o - https://downloads.openwrt.org/releases/23.05.5/targets/x86/64/openwrt-sdk-23.05.5-x86-64_gcc-12.3.0_musl.Linux-x86_64.tar.xz | tar -Jxvf -
|
curl -o - https://downloads.openwrt.org/releases/23.05.5/targets/x86/64/openwrt-sdk-23.05.5-x86-64_gcc-12.3.0_musl.Linux-x86_64.tar.xz | tar -Jxv
|
||||||
cd openwrt-sdk-23.05.5-x86-64_gcc-12.3.0_musl.Linux-x86_64
|
cd openwrt-sdk-23.05.5-x86-64_gcc-12.3.0_musl.Linux-x86_64
|
||||||
|
|
||||||
curl -o - https://downloads.openwrt.org/snapshots/targets/x86/64/openwrt-sdk-x86-64_gcc-13.3.0_musl.Linux-x86_64.tar.zst | tar --zstd -xvf -
|
curl -o - https://downloads.openwrt.org/snapshots/targets/x86/64/openwrt-sdk-x86-64_gcc-13.3.0_musl.Linux-x86_64.tar.zst | tar --zstd -xv
|
||||||
cd openwrt-sdk-x86-64_gcc-13.3.0_musl.Linux-x86_64
|
cd openwrt-sdk-x86-64_gcc-13.3.0_musl.Linux-x86_64
|
||||||
|
|
||||||
3) Install required libs
|
3) Install required libs
|
||||||
@ -48,7 +48,7 @@ static build : make CFLAGS=-static package/{tpws,nfqws,mdig,ip2net}/compile
|
|||||||
executables only : build_dir/target/<progname>
|
executables only : build_dir/target/<progname>
|
||||||
ipk or apk packages : bin/packages/*/base
|
ipk or apk packages : bin/packages/*/base
|
||||||
|
|
||||||
8) Installating to openwrt to use with zapret
|
8) Installing to openwrt to use with zapret
|
||||||
|
|
||||||
zapret with or without binaries should be already installed in /opt/zapret.
|
zapret with or without binaries should be already installed in /opt/zapret.
|
||||||
Install ipk's or apk's with all compiled progs using opkg or apk.
|
Install ipk's or apk's with all compiled progs using opkg or apk.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
debian,ubuntu :
|
debian,ubuntu :
|
||||||
|
|
||||||
apt install make gcc zlib1g-dev libcap-dev libnetfilter-queue-dev
|
apt install make gcc zlib1g-dev libcap-dev libnetfilter-queue-dev libsystemd-dev
|
||||||
make -C /opt/zapret
|
make -C /opt/zapret systemd
|
||||||
|
|
||||||
FreeBSD :
|
FreeBSD :
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> Не пишите в issue вопросы типа "как скопировать файл", "как скачать", "как
|
> Не пишите в issue вопросы типа "как скопировать файл", "как скачать", "как
|
||||||
> запустить", ... То есть все , что касается базовых навыков обращения с ОС
|
> запустить" и т.п. То есть все, что касается базовых навыков обращения с ОС
|
||||||
> linux. Эти вопросы будут закрывать сразу. Если у вас подобные вопросы
|
> Linux. Эти вопросы будут закрывать сразу. Если у вас подобные вопросы
|
||||||
> возникают, рекомендую не использовать данный софт или искать помощь где-то в
|
> возникают, рекомендую не использовать данный софт или искать помощь где-то в
|
||||||
> другом месте. То же самое могу сказать тем, кто хочет нажать 1 кнопку, чтобы
|
> другом месте. То же самое могу сказать тем, кто хочет нажать 1 кнопку, чтобы
|
||||||
> все заработало, и совсем не хочет читать и изучать. Увы, такое не подвезли и
|
> все заработало, и совсем не хочет читать и изучать. Увы, такое не подвезли и
|
||||||
@ -50,6 +50,8 @@
|
|||||||
> образ `squashfs` с помощью `image builder` и перешить этим вариантом роутер.
|
> образ `squashfs` с помощью `image builder` и перешить этим вариантом роутер.
|
||||||
|
|
||||||
1. Скачайте последний [tar.gz релиз](https://github.com/bol-van/zapret/releases) в /tmp, распакуйте его, затем удалите архив.
|
1. Скачайте последний [tar.gz релиз](https://github.com/bol-van/zapret/releases) в /tmp, распакуйте его, затем удалите архив.
|
||||||
|
Для openwrt и прошивок используйте вариант `openwrt-embedded`.
|
||||||
|
Для экономия места в /tmp можно качать через curl в stdout и сразу распаковывать.
|
||||||
|
|
||||||
2. Убедитесь, что у вас отключены все средства обхода блокировок, в том числе и
|
2. Убедитесь, что у вас отключены все средства обхода блокировок, в том числе и
|
||||||
сам zapret. Гарантированно уберет zapret скрипт `uninstall_easy.sh`.
|
сам zapret. Гарантированно уберет zapret скрипт `uninstall_easy.sh`.
|
||||||
@ -87,14 +89,15 @@
|
|||||||
>
|
>
|
||||||
> Проверить работает ли этот вариант можно так:
|
> Проверить работает ли этот вариант можно так:
|
||||||
> ```sh
|
> ```sh
|
||||||
> $ dig -p 53 @77.88.8.88 rutracker.org dig -p 1253 @77.88.8.88 rutracker.org
|
> $ dig -p 53 @77.88.8.88 rutracker.org
|
||||||
|
> $ dig -p 1253 @77.88.8.88 rutracker.org
|
||||||
> ```
|
> ```
|
||||||
>
|
>
|
||||||
> Если DNS действительно подменяется, и ответ на эти 2 команды разный,
|
> Если DNS действительно подменяется, и ответ на эти 2 команды разный,
|
||||||
> значит метод вероятно работает.
|
> значит метод вероятно работает.
|
||||||
>
|
>
|
||||||
> В openwrt DNS на нестандартном порту можно прописать в `/etc/config/dhcp`
|
> В openwrt DNS на нестандартном порту можно прописать в `/etc/config/dhcp`
|
||||||
> таким способом :
|
> таким способом:
|
||||||
>
|
>
|
||||||
> ```
|
> ```
|
||||||
> config dnsmasq
|
> config dnsmasq
|
||||||
@ -156,12 +159,12 @@
|
|||||||
>
|
>
|
||||||
> Далее, имея понимание что работает на http, https, quic нужно
|
> Далее, имея понимание что работает на http, https, quic нужно
|
||||||
> сконструировать параметры запуска `tpws` и/или `nfqws` с использованием
|
> сконструировать параметры запуска `tpws` и/или `nfqws` с использованием
|
||||||
> мультистратегии. Как работают мультистратегии описано в readme.txt.
|
> мультистратегии. Как работают мультистратегии описано в [readme.md](./readme.md#множественные-стратегии).
|
||||||
>
|
>
|
||||||
> Если кратко, то обычно параметры конструируются так:
|
> Если кратко, то обычно параметры конструируются так:
|
||||||
> ```sh
|
> ```sh
|
||||||
> "--filter-udp=443 'параметры для quic' <HOSTLIST_NOAUTO> --new
|
> "--filter-udp=443 'параметры для quic' <HOSTLIST_NOAUTO> --new
|
||||||
> --filter-tcp=80,443 'обьединенные параметры для http и https' <HOSTLIST>"
|
> --filter-tcp=80,443 'объединенные параметры для http и https' <HOSTLIST>"
|
||||||
> ```
|
> ```
|
||||||
>
|
>
|
||||||
> Или так:
|
> Или так:
|
||||||
@ -191,7 +194,7 @@
|
|||||||
> "--filter-l3=ipv4 --filter-udp=443 lпараметры для quic ipv4' <HOSTLIST_NOAUTO> --new
|
> "--filter-l3=ipv4 --filter-udp=443 lпараметры для quic ipv4' <HOSTLIST_NOAUTO> --new
|
||||||
> --filter-l3=ipv4 --filter-tcp=80 'параметры для http ipv4' <HOSTLIST> --new
|
> --filter-l3=ipv4 --filter-tcp=80 'параметры для http ipv4' <HOSTLIST> --new
|
||||||
> --filter-l3=ipv4 --filter-tcp=443 'параметры для https ipv4' <HOSTLIST> --new
|
> --filter-l3=ipv4 --filter-tcp=443 'параметры для https ipv4' <HOSTLIST> --new
|
||||||
> --filter-l3=ipv6 --filter-udp=443 "параметры для quic ipv6" <HOSTLIST_NOAUTO> --new
|
> --filter-l3=ipv6 --filter-udp=443 'параметры для quic ipv6' <HOSTLIST_NOAUTO> --new
|
||||||
> --filter-l3=ipv6 --filter-tcp=80 'параметры для http ipv6' <HOSTLIST> --new
|
> --filter-l3=ipv6 --filter-tcp=80 'параметры для http ipv6' <HOSTLIST> --new
|
||||||
> --filter-l3=ipv6 --filter-tcp=443 'параметры для https ipv6' <HOSTLIST>"
|
> --filter-l3=ipv6 --filter-tcp=443 'параметры для https ipv6' <HOSTLIST>"
|
||||||
> ```
|
> ```
|
||||||
|
@ -59,7 +59,7 @@ _"Совсем ничего не могу, все очень сложно, да
|
|||||||
|
|
||||||
1) Скачайте и распакуйте архив https://github.com/bol-van/zapret-win-bundle/archive/refs/heads/master.zip.
|
1) Скачайте и распакуйте архив https://github.com/bol-van/zapret-win-bundle/archive/refs/heads/master.zip.
|
||||||
|
|
||||||
2) Если у вас Windows 7 x64, читайте [docs/windows.md](./windows.md). Без описанной там подготовки может не работать.
|
2) Если у вас Windows 7 x64, однократно запустите `win7/install_win7.cmd`. Батник заменит файлы windivert на совместимую с Windows 7 версию.
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> Для 32-битных систем Windows нет готового полного варианта.
|
> Для 32-битных систем Windows нет готового полного варианта.
|
||||||
@ -123,7 +123,7 @@ blockcheck перейдет в этом случае на **DoH** _(DNS over HTT
|
|||||||
> она стабильна, на третьих полный хаос, и проще отказаться.
|
> она стабильна, на третьих полный хаос, и проще отказаться.
|
||||||
>
|
>
|
||||||
> Далее, имея понимание что работает на http, https, quic, нужно сконструировать параметры запуска winws
|
> Далее, имея понимание что работает на http, https, quic, нужно сконструировать параметры запуска winws
|
||||||
> с использованием мультистратегии. Как работают мультистратегии описано в [readme.md](./readme.md).
|
> с использованием мультистратегии. Как работают мультистратегии описано в [readme.md](./readme.md#множественные-стратегии).
|
||||||
>
|
>
|
||||||
> Прежде всего вам нужно собрать фильтр перехватываемого трафика. Это делается через параметры
|
> Прежде всего вам нужно собрать фильтр перехватываемого трафика. Это делается через параметры
|
||||||
> `--wf-l3`, `--wf-tcp`, `--wf-udp`.
|
> `--wf-l3`, `--wf-tcp`, `--wf-udp`.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# zapret v.69
|
# zapret v70.6
|
||||||
|
|
||||||
# SCAMMER WARNING
|
# SCAMMER WARNING
|
||||||
|
|
||||||
@ -19,6 +19,7 @@ ___
|
|||||||
- [nfqws](#nfqws)
|
- [nfqws](#nfqws)
|
||||||
- [DPI desync attack](#dpi-desync-attack)
|
- [DPI desync attack](#dpi-desync-attack)
|
||||||
- [Fakes](#fakes)
|
- [Fakes](#fakes)
|
||||||
|
- [Fake mods](#fake-mods)
|
||||||
- [TCP segmentation](#tcp-segmentation)
|
- [TCP segmentation](#tcp-segmentation)
|
||||||
- [Sequence numbers overlap](#sequence-numbers-overlap)
|
- [Sequence numbers overlap](#sequence-numbers-overlap)
|
||||||
- [ipv6 specific modes](#ipv6-specific-modes)
|
- [ipv6 specific modes](#ipv6-specific-modes)
|
||||||
@ -119,7 +120,7 @@ You need to run them with the necessary parameters and redirect certain traffic
|
|||||||
when blocked domains are queried. If this is the case change DNS to public ones, such as 8.8.8.8 or 1.1.1.1.Sometimes ISP hijacks queries to any DNS server. Dnscrypt or dns-over-tls help.
|
when blocked domains are queried. If this is the case change DNS to public ones, such as 8.8.8.8 or 1.1.1.1.Sometimes ISP hijacks queries to any DNS server. Dnscrypt or dns-over-tls help.
|
||||||
* If blocking is done by IP.
|
* If blocking is done by IP.
|
||||||
* If a connection passes through a filter capable of reconstructing a TCP connection, and which
|
* If a connection passes through a filter capable of reconstructing a TCP connection, and which
|
||||||
follows all standards. For example, we are routed to squid. Connection goes through the full OS tcpip stack, fragmentation disappears immediately as a means of circumvention. Squid is correct, it will find everything as it should, it is useless to deceive him. BUT. Only small providers can afford using squid, since it is very resource intensive. Large companies usually use DPI, which is designed for much greater bandwidth.
|
follows all standards. For example, we are routed to squid. Connection goes through the full OS tcpip stack. This project targets DPI only, not full OS stack and not server applications.
|
||||||
|
|
||||||
## nfqws
|
## nfqws
|
||||||
|
|
||||||
@ -131,6 +132,9 @@ nfqws takes the following parameters:
|
|||||||
@<config_file> ; read file for options. must be the only argument. other options are ignored.
|
@<config_file> ; read file for options. must be the only argument. other options are ignored.
|
||||||
|
|
||||||
--debug=0|1
|
--debug=0|1
|
||||||
|
--dry-run ; verify parameters and exit with code 0 if successful
|
||||||
|
--version ; print version and exit
|
||||||
|
--comment ; any text (ignored)
|
||||||
--qnum=<nfqueue_number>
|
--qnum=<nfqueue_number>
|
||||||
--daemon ; daemonize
|
--daemon ; daemonize
|
||||||
--pidfile=<filename> ; write pid to file
|
--pidfile=<filename> ; write pid to file
|
||||||
@ -146,6 +150,7 @@ nfqws takes the following parameters:
|
|||||||
--hostspell ; exact spelling of "Host" header. must be 4 chars. default is "host"
|
--hostspell ; exact spelling of "Host" header. must be 4 chars. default is "host"
|
||||||
--hostnospace ; remove space after Host: and add it to User-Agent: to preserve packet size
|
--hostnospace ; remove space after Host: and add it to User-Agent: to preserve packet size
|
||||||
--domcase ; mix domain case : Host: TeSt.cOm
|
--domcase ; mix domain case : Host: TeSt.cOm
|
||||||
|
--methodeol ; add '\n' before method and remove space after Host:
|
||||||
--dpi-desync=[<mode0>,]<mode>[,<mode2>] ; try to desync dpi state. modes : synack fake fakeknown rst rstack hopbyhop destopt ipfrag1 multisplit multidisorder fakedsplit fakeddisorder ipfrag2 udplen tamper
|
--dpi-desync=[<mode0>,]<mode>[,<mode2>] ; try to desync dpi state. modes : synack fake fakeknown rst rstack hopbyhop destopt ipfrag1 multisplit multidisorder fakedsplit fakeddisorder ipfrag2 udplen tamper
|
||||||
--dpi-desync-fwmark=<int|0xHEX> ; override fwmark for desync packet. default = 0x40000000 (1073741824)
|
--dpi-desync-fwmark=<int|0xHEX> ; override fwmark for desync packet. default = 0x40000000 (1073741824)
|
||||||
--dpi-desync-ttl=<int> ; set ttl for desync packet
|
--dpi-desync-ttl=<int> ; set ttl for desync packet
|
||||||
@ -161,6 +166,7 @@ nfqws takes the following parameters:
|
|||||||
; fakedsplit/fakeddisorder use first l7-protocol-compatible parameter if present, first abs value otherwise
|
; fakedsplit/fakeddisorder use first l7-protocol-compatible parameter if present, first abs value otherwise
|
||||||
--dpi-desync-split-seqovl=N|-N|marker+N|marker-N ; use sequence overlap before first sent original split segment
|
--dpi-desync-split-seqovl=N|-N|marker+N|marker-N ; use sequence overlap before first sent original split segment
|
||||||
--dpi-desync-split-seqovl-pattern=<filename>|0xHEX ; pattern for the fake part of overlap
|
--dpi-desync-split-seqovl-pattern=<filename>|0xHEX ; pattern for the fake part of overlap
|
||||||
|
--dpi-desync-fakedsplit-pattern=<filename>|0xHEX ; fake pattern for fakedsplit/fakeddisorder
|
||||||
--dpi-desync-ipfrag-pos-tcp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 8.
|
--dpi-desync-ipfrag-pos-tcp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 8.
|
||||||
--dpi-desync-ipfrag-pos-udp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 32.
|
--dpi-desync-ipfrag-pos-udp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 32.
|
||||||
--dpi-desync-badseq-increment=<int|0xHEX> ; badseq fooling seq signed increment. default -10000
|
--dpi-desync-badseq-increment=<int|0xHEX> ; badseq fooling seq signed increment. default -10000
|
||||||
@ -168,30 +174,38 @@ nfqws takes the following parameters:
|
|||||||
--dpi-desync-any-protocol=0|1 ; 0(default)=desync only http and tls 1=desync any nonempty data packet
|
--dpi-desync-any-protocol=0|1 ; 0(default)=desync only http and tls 1=desync any nonempty data packet
|
||||||
--dpi-desync-fake-http=<filename>|0xHEX ; file containing fake http request
|
--dpi-desync-fake-http=<filename>|0xHEX ; file containing fake http request
|
||||||
--dpi-desync-fake-tls=<filename>|0xHEX ; file containing fake TLS ClientHello (for https)
|
--dpi-desync-fake-tls=<filename>|0xHEX ; file containing fake TLS ClientHello (for https)
|
||||||
|
--dpi-desync-fake-tls-mod=mod[,mod] ; comma separated list of TLS fake mods. available mods : none,rnd,rndsni,sni=<sni>,dupsid,padencap
|
||||||
--dpi-desync-fake-unknown=<filename>|0xHEX ; file containing unknown protocol fake payload
|
--dpi-desync-fake-unknown=<filename>|0xHEX ; file containing unknown protocol fake payload
|
||||||
--dpi-desync-fake-syndata=<filename>|0xHEX ; file containing SYN data payload
|
--dpi-desync-fake-syndata=<filename>|0xHEX ; file containing SYN data payload
|
||||||
--dpi-desync-fake-quic=<filename>|0xHEX ; file containing fake QUIC Initial
|
--dpi-desync-fake-quic=<filename>|0xHEX ; file containing fake QUIC Initial
|
||||||
--dpi-desync-fake-wireguard=<filename>|0xHEX ; file containing fake wireguard handshake initiation
|
--dpi-desync-fake-wireguard=<filename>|0xHEX ; file containing fake wireguard handshake initiation
|
||||||
--dpi-desync-fake-dht=<filename>|0xHEX ; file containing fake DHT (d1..e)
|
--dpi-desync-fake-dht=<filename>|0xHEX ; file containing fake DHT (d1..e)
|
||||||
|
--dpi-desync-fake-discord=<filename>|0xHEX ; file containing fake Discord voice connection initiation packet (IP Discovery)
|
||||||
|
--dpi-desync-fake-stun=<filename>|0xHEX ; file containing fake STUN message
|
||||||
--dpi-desync-fake-unknown-udp=<filename>|0xHEX ; file containing unknown udp protocol fake payload
|
--dpi-desync-fake-unknown-udp=<filename>|0xHEX ; file containing unknown udp protocol fake payload
|
||||||
--dpi-desync-udplen-increment=<int> ; increase or decrease udp packet length by N bytes (default 2). negative values decrease length.
|
--dpi-desync-udplen-increment=<int> ; increase or decrease udp packet length by N bytes (default 2). negative values decrease length.
|
||||||
--dpi-desync-udplen-pattern=<filename>|0xHEX ; udp tail fill pattern
|
--dpi-desync-udplen-pattern=<filename>|0xHEX ; udp tail fill pattern
|
||||||
--dpi-desync-start=[n|d|s]N ; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N
|
--dpi-desync-start=[n|d|s]N ; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N
|
||||||
--dpi-desync-cutoff=[n|d|s]N ; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
--dpi-desync-cutoff=[n|d|s]N ; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
||||||
--hostlist=<filename> ; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
--hostlist=<filename> ; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply if not prefixed with `^`, gzip supported, multiple hostlists allowed)
|
||||||
--hostlist-exclude=<filename> ; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
--hostlist-domains=<domain_list> ; comma separated fixed domain list
|
||||||
|
--hostlist-exclude=<filename> ; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply if not prefixed with `^`, gzip supported, multiple hostlists allowed)
|
||||||
|
--hostlist-exclude-domains=<domain_list> ; comma separated fixed domain list
|
||||||
--hostlist-auto=<filename> ; detect DPI blocks and build hostlist automatically
|
--hostlist-auto=<filename> ; detect DPI blocks and build hostlist automatically
|
||||||
--hostlist-auto-fail-threshold=<int> ; how many failed attempts cause hostname to be added to auto hostlist (default : 3)
|
--hostlist-auto-fail-threshold=<int> ; how many failed attempts cause hostname to be added to auto hostlist (default : 3)
|
||||||
--hostlist-auto-fail-time=<int> ; all failed attemps must be within these seconds (default : 60)
|
--hostlist-auto-fail-time=<int> ; all failed attemps must be within these seconds (default : 60)
|
||||||
--hostlist-auto-retrans-threshold=<int> ; how many request retransmissions cause attempt to fail (default : 3)
|
--hostlist-auto-retrans-threshold=<int> ; how many request retransmissions cause attempt to fail (default : 3)
|
||||||
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
||||||
--new ; begin new strategy
|
--new ; begin new strategy (new profile)
|
||||||
|
--skip ; do not use this profile
|
||||||
--filter-l3=ipv4|ipv6 ; L3 protocol filter. multiple comma separated values allowed.
|
--filter-l3=ipv4|ipv6 ; L3 protocol filter. multiple comma separated values allowed.
|
||||||
--filter-tcp=[~]port1[-port2]|* ; TCP port filter. ~ means negation. setting tcp and not setting udp filter denies udp. comma separated list supported.
|
--filter-tcp=[~]port1[-port2]|* ; TCP port filter. ~ means negation. setting tcp and not setting udp filter denies udp. comma separated list supported.
|
||||||
--filter-udp=[~]port1[-port2]|* ; UDP port filter. ~ means negation. setting udp and not setting tcp filter denies tcp. comma separated list supported.
|
--filter-udp=[~]port1[-port2]|* ; UDP port filter. ~ means negation. setting udp and not setting tcp filter denies tcp. comma separated list supported.
|
||||||
--filter-l7=[http|tls|quic|wireguard|dht|unknown] ; L6-L7 protocol filter. multiple comma separated values allowed.
|
--filter-l7=<proto> ; L6-L7 protocol filter. multiple comma separated values allowed. proto: http tls quic wireguard dht discord stun unknown
|
||||||
--ipset=<filename> ; ipset include filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
--ipset=<filename> ; ipset include filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||||
|
--ipset-ip=<ip_list> ; comma separated fixed subnet list
|
||||||
--ipset-exclude=<filename> ; ipset exclude filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
--ipset-exclude=<filename> ; ipset exclude filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||||
|
--ipset-exclude-ip=<ip_list> ; comma separated fixed subnet list
|
||||||
```
|
```
|
||||||
|
|
||||||
### DPI desync attack
|
### DPI desync attack
|
||||||
@ -207,7 +221,9 @@ There're attacks based on TCP sequence numbers. Methods can be combined in many
|
|||||||
|
|
||||||
Fakes are separate generated by nfqws packets carrying false information for DPI. They must either not reach the server or be rejected by it. Otherwise TCP connection or data stream would be broken. There're multiple ways to solve this task.
|
Fakes are separate generated by nfqws packets carrying false information for DPI. They must either not reach the server or be rejected by it. Otherwise TCP connection or data stream would be broken. There're multiple ways to solve this task.
|
||||||
|
|
||||||
* **md5sig** does not work on all servers
|
* **md5sig** does not work on all servers. It typically works only on Linux servers. MD5 tcp option requires additional space in TCP header
|
||||||
|
and can cause MTU overflow during fakedsplit/fakeddisorder on low positions when multisegment query (TLS kyber) is transmitted.
|
||||||
|
`nfqws` cannot redistribute data between original TCP segments. The error displayed is 'message too long'.
|
||||||
* **badsum** doesn't work if your device is behind NAT which does not pass invalid packets.
|
* **badsum** doesn't work if your device is behind NAT which does not pass invalid packets.
|
||||||
The most common Linux NAT router configuration does not pass them. Most home routers are Linux based.
|
The most common Linux NAT router configuration does not pass them. Most home routers are Linux based.
|
||||||
The default sysctl configuration `net.netfilter.nf_conntrack_checksum=1` causes contrack to verify tcp and udp checksums
|
The default sysctl configuration `net.netfilter.nf_conntrack_checksum=1` causes contrack to verify tcp and udp checksums
|
||||||
@ -252,12 +268,43 @@ Fakes are separate generated by nfqws packets carrying false information for DPI
|
|||||||
`--dpi-desync-fooling` takes multiple comma separated values.
|
`--dpi-desync-fooling` takes multiple comma separated values.
|
||||||
|
|
||||||
|
|
||||||
|
Multiple parameters `--dpi-desync-fake-???` are supported except for the `--dpi-desync-fake-syndata`.
|
||||||
|
Fakes are sent in the specified order. `--dpi-desync-repeats` resends each fake.
|
||||||
|
Resulting order would be : `fake1 fake1 fake1 fake2 fake2 fake2 fake3 fake3 fake3 .....`
|
||||||
|
|
||||||
|
|
||||||
|
### FAKE mods
|
||||||
|
|
||||||
|
**nfqws** has built-in TLS fake. It can be customized with `--dpi-desync-fake-tls` option.
|
||||||
|
Customized fake data can be anything - valid TLS Client Hello or arbitrary data.
|
||||||
|
It's possible to use TLS Client Hello with any fingerprint and any SNI.
|
||||||
|
|
||||||
|
**nfqws** can do some modifications of valid TLS Client Hello fakes in runtime with `--dpi-desync-fake-tls-mod` option.
|
||||||
|
|
||||||
|
* `none`. Do not do any mods.
|
||||||
|
* `rnd`. Randomize `random` and `session id` fields. Applied on every request.
|
||||||
|
* `rndsni`. Randomize SNI. If SNI >=7 symbols random SLD is applied with known TLD. Otherwise filled with random symbols. Applied only once at startup.
|
||||||
|
* `dupsid`. Copy `session ID` from original TLS Client Hello. Takes precedence over `rnd`. Applied on every request.
|
||||||
|
* `sni=<sni>`. Set specified SNI value. Changes TLS fake length, fixes lengths in TLS structure. Applied once at startup before `rndsni`.
|
||||||
|
* `padencap`. Padding extension is extended by original TLS Client Hello size (including multi packet variation with kyber). Padding extension is added to the end if not present, otherwise it must be the last extension. All lengths are increased. Fake size is not changed. Can be useful if DPI does not analyze sequence numbers properly. Applied on every request.
|
||||||
|
|
||||||
|
By default if custom fake is not defined `rnd,rndsni,dupsid` mods are applied. If defined - `none`.
|
||||||
|
This behaviour is compatible with previous versions with addition of `dupsid`.
|
||||||
|
|
||||||
|
If multiple TLS fakes are present each one takes the last mod.
|
||||||
|
If a mod is specified after fake it replaces previous mod.
|
||||||
|
This way it's possible to use different mods for every TLS fake.
|
||||||
|
|
||||||
|
If a mod is set to non-TLS fake it causes error. Use `--dpi-desync-fake-tls-mod=none'.
|
||||||
|
|
||||||
|
Example : `--dpi-desync-fake-tls=iana_org.bin --dpi-desync-fake-tls-mod=rndsni --dpi-desync-fake-tls=0xaabbccdd --dpi-desync-fake-tls-mod=none'
|
||||||
|
|
||||||
### TCP segmentation
|
### TCP segmentation
|
||||||
|
|
||||||
* `multisplit`. split request at specified in `--dpi-desync-split-pos` positions
|
* `multisplit`. split request at specified in `--dpi-desync-split-pos` positions
|
||||||
* `multidisorder`. same as `multisplit` but send in reverse order
|
* `multidisorder`. same as `multisplit` but send in reverse order
|
||||||
* `fakedsplit`. split request into 2 segments adding fakes in the middle of them : fake 1st segment, 1st segment, fake 1st segment, 2nd segment
|
* `fakedsplit`. split request into 2 segments adding fakes in the middle of them : fake 1st segment, 1st segment, fake 1st segment, fake 2nd segment, 2nd segment, fake 2nd segment
|
||||||
* `fakeddisorder`. same as `fakedsplit` but with another order : 2nd segment, fake 1st segment, 1st segment, fake 1st segment
|
* `fakeddisorder`. same as `fakedsplit` but with another order : fake 2nd segment, 2nd segment, fake 2nd segment, fake 1st segment, 1st segment, fake 1st segment
|
||||||
|
|
||||||
Positions are defined by markers.
|
Positions are defined by markers.
|
||||||
|
|
||||||
@ -267,7 +314,7 @@ Positions are defined by markers.
|
|||||||
|
|
||||||
Relative positions :
|
Relative positions :
|
||||||
|
|
||||||
* **method** - HTTP method start ('GET', 'POST', 'HEAD', ...). Method is usually always at position 0 but also supported `--methodeol` fooling by **tpws**. If fooled position can become 1 or 2.
|
* **method** - HTTP method start ('GET', 'POST', 'HEAD', ...). Method is usually always at position 0 but can shift because of `--methodeol` fooling. If fooled position can become 1 or 2.
|
||||||
* **host** - hostname start in a known protocol (http, TLS)
|
* **host** - hostname start in a known protocol (http, TLS)
|
||||||
* **endhost** - the byte next to the last hostname's byte
|
* **endhost** - the byte next to the last hostname's byte
|
||||||
* **sld** - second level domain start in the hostname
|
* **sld** - second level domain start in the hostname
|
||||||
@ -434,7 +481,7 @@ This option can resist DPIs that track outgoing UDP packet sizes.
|
|||||||
Requires that application protocol does not depend on udp payload size.
|
Requires that application protocol does not depend on udp payload size.
|
||||||
|
|
||||||
QUIC initial packets are recognized. Decryption and hostname extraction is supported so `--hostlist` parameter will work.
|
QUIC initial packets are recognized. Decryption and hostname extraction is supported so `--hostlist` parameter will work.
|
||||||
Wireguard handshake initiation and DHT packets are also recognized.
|
Wireguard handshake initiation, DHT, STUN and [Discord Voice IP Discovery](https://discord.com/developers/docs/topics/voice-connections#ip-discovery) packets are also recognized.
|
||||||
For other protocols desync use `--dpi-desync-any-protocol`.
|
For other protocols desync use `--dpi-desync-any-protocol`.
|
||||||
|
|
||||||
Conntrack supports udp. `--dpi-desync-cutoff` will work. UDP conntrack timeout can be set in the 4th parameter of `--ctrack-timeouts`.
|
Conntrack supports udp. `--dpi-desync-cutoff` will work. UDP conntrack timeout can be set in the 4th parameter of `--ctrack-timeouts`.
|
||||||
@ -632,6 +679,8 @@ tpws is transparent proxy.
|
|||||||
|
|
||||||
--debug=0|1|2|syslog|@<filename> ; 1 and 2 means log to console and set debug level. for other targets use --debug-level.
|
--debug=0|1|2|syslog|@<filename> ; 1 and 2 means log to console and set debug level. for other targets use --debug-level.
|
||||||
--debug-level=0|1|2 ; specify debug level for syslog and @<filename>
|
--debug-level=0|1|2 ; specify debug level for syslog and @<filename>
|
||||||
|
--dry-run ; verify parameters and exit with code 0 if successful
|
||||||
|
--version ; print version and exit
|
||||||
--bind-addr=<v4_addr>|<v6_addr> ; for v6 link locals append %interface_name : fe80::1%br-lan
|
--bind-addr=<v4_addr>|<v6_addr> ; for v6 link locals append %interface_name : fe80::1%br-lan
|
||||||
--bind-iface4=<interface_name> ; bind to the first ipv4 addr of interface
|
--bind-iface4=<interface_name> ; bind to the first ipv4 addr of interface
|
||||||
--bind-iface6=<interface_name> ; bind to the first ipv6 addr of interface
|
--bind-iface6=<interface_name> ; bind to the first ipv6 addr of interface
|
||||||
@ -663,15 +712,20 @@ tpws is transparent proxy.
|
|||||||
; its worth to make a reserve with 1.5 multiplier. by default maxfiles is (X*connections)*1.5+16
|
; its worth to make a reserve with 1.5 multiplier. by default maxfiles is (X*connections)*1.5+16
|
||||||
--max-orphan-time=<sec> ; if local leg sends something and closes and remote leg is still connecting then cancel connection attempt after N seconds
|
--max-orphan-time=<sec> ; if local leg sends something and closes and remote leg is still connecting then cancel connection attempt after N seconds
|
||||||
|
|
||||||
--new ; begin new strategy
|
--new ; begin new strategy (new profile)
|
||||||
|
--skip ; do not use this profile
|
||||||
--filter-l3=ipv4|ipv6 ; L3 protocol filter. multiple comma separated values allowed.
|
--filter-l3=ipv4|ipv6 ; L3 protocol filter. multiple comma separated values allowed.
|
||||||
--filter-tcp=[~]port1[-port2]|* ; TCP port filter. ~ means negation. comma separated list supported.
|
--filter-tcp=[~]port1[-port2]|* ; TCP port filter. ~ means negation. comma separated list supported.
|
||||||
--filter-l7=[http|tls|unknown] ; L6-L7 protocol filter. multiple comma separated values allowed.
|
--filter-l7=[http|tls|unknown] ; L6-L7 protocol filter. multiple comma separated values allowed.
|
||||||
--ipset=<filename> ; ipset include filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
--ipset=<filename> ; ipset include filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||||
|
--ipset-ip=<ip_list> ; comma separated fixed subnet list
|
||||||
--ipset-exclude=<filename> ; ipset exclude filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
--ipset-exclude=<filename> ; ipset exclude filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||||
|
--ipset-exclude-ip=<ip_list> ; comma separated fixed subnet list
|
||||||
|
|
||||||
--hostlist=<filename> ; only act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
--hostlist=<filename> ; only act on hosts in the list (one host per line, subdomains auto apply if not prefixed with '^', gzip supported, multiple hostlists allowed)
|
||||||
--hostlist-exclude=<filename> ; do not act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
--hostlist-domains=<domain_list> ; comma separated fixed domain list
|
||||||
|
--hostlist-exclude=<filename> ; do not act on hosts in the list (one host per line, subdomains auto apply if not prefixed with '^', gzip supported, multiple hostlists allowed)
|
||||||
|
--hostlist-exclude-domains=<domain_list> ; comma separated fixed domain list
|
||||||
--hostlist-auto=<filename> ; detect DPI blocks and build hostlist automatically
|
--hostlist-auto=<filename> ; detect DPI blocks and build hostlist automatically
|
||||||
--hostlist-auto-fail-threshold=<int> ; how many failed attempts cause hostname to be added to auto hostlist (default : 3)
|
--hostlist-auto-fail-threshold=<int> ; how many failed attempts cause hostname to be added to auto hostlist (default : 3)
|
||||||
--hostlist-auto-fail-time=<int> ; all failed attemps must be within these seconds (default : 60)
|
--hostlist-auto-fail-time=<int> ; all failed attemps must be within these seconds (default : 60)
|
||||||
@ -701,7 +755,7 @@ tpws is transparent proxy.
|
|||||||
--daemon ; daemonize
|
--daemon ; daemonize
|
||||||
--pidfile=<filename> ; write pid to file
|
--pidfile=<filename> ; write pid to file
|
||||||
--user=<username> ; drop root privs
|
--user=<username> ; drop root privs
|
||||||
--uid=uid[:gid] ; drop root privs
|
--uid=uid[:gid] ; drop root privs
|
||||||
```
|
```
|
||||||
|
|
||||||
### TCP segmentation in tpws
|
### TCP segmentation in tpws
|
||||||
@ -949,8 +1003,10 @@ If all include lists are empty it works like no include lists exist at all.
|
|||||||
If you need "all except" mode you dont have to delete zapret-hosts-users.txt. Just make it empty.
|
If you need "all except" mode you dont have to delete zapret-hosts-users.txt. Just make it empty.
|
||||||
|
|
||||||
Subdomains auto apply. For example, "ru" in the list affects "*.ru" .
|
Subdomains auto apply. For example, "ru" in the list affects "*.ru" .
|
||||||
|
`^` prefix symbol disables subdomain match.
|
||||||
|
|
||||||
**tpws** and **nfqws** automatically reload lists if their modification date is changed.
|
**tpws** and **nfqws** automatically reload lists if their modification time or file size is changed.
|
||||||
|
HUP signal forcibly reloads all lists.
|
||||||
|
|
||||||
When filtering by domain name, daemons should run without filtering by ipset.
|
When filtering by domain name, daemons should run without filtering by ipset.
|
||||||
When using large regulator lists estimate the amount of RAM on the router !
|
When using large regulator lists estimate the amount of RAM on the router !
|
||||||
@ -1395,12 +1451,8 @@ If this is the case then run another script in background and add some delay the
|
|||||||
|
|
||||||
Are welcome here :
|
Are welcome here :
|
||||||
|
|
||||||
<img src=https://cdn-icons-png.flaticon.com/16/14446/14446252.png alt="USDT" style="vertical-align: middle;"/> USDT
|
USDT `0x3d52Ce15B7Be734c53fc9526ECbAB8267b63d66E`
|
||||||
```
|
|
||||||
0x3d52Ce15B7Be734c53fc9526ECbAB8267b63d66E
|
|
||||||
```
|
|
||||||
|
|
||||||
<img src=https://cdn-icons-png.flaticon.com/16/5968/5968260.png alt="USDT" style="vertical-align: middle;"/> BTC
|
BTC `bc1qhqew3mrvp47uk2vevt5sctp7p2x9m7m5kkchve`
|
||||||
```
|
|
||||||
bc1qhqew3mrvp47uk2vevt5sctp7p2x9m7m5kkchve
|
ETH `0x3d52Ce15B7Be734c53fc9526ECbAB8267b63d66E`
|
||||||
```
|
|
||||||
|
788
docs/readme.md
788
docs/readme.md
File diff suppressed because it is too large
Load Diff
@ -101,10 +101,11 @@ There are several options :
|
|||||||
Replace these 2 files in every location they are present.
|
Replace these 2 files in every location they are present.
|
||||||
In `zapret-win-bundle` they are in `zapret-winws` и `blockcheck/zapret/nfq` folders.
|
In `zapret-win-bundle` they are in `zapret-winws` и `blockcheck/zapret/nfq` folders.
|
||||||
However this option still requires 10+ year old patch that enables SHA256 signatures.
|
However this option still requires 10+ year old patch that enables SHA256 signatures.
|
||||||
|
If you're using win bundle you can simply run `win7\install_win7.cmd`
|
||||||
|
|
||||||
2. [Hack ESU](https://hackandpwn.com/windows-7-esu-patching)
|
3. [Hack ESU](https://hackandpwn.com/windows-7-esu-patching)
|
||||||
|
|
||||||
3. Use `UpdatePack7R2` from simplix : https://blog.simplix.info
|
4. Use `UpdatePack7R2` from simplix : https://blog.simplix.info
|
||||||
If you are in Russia or Belarus temporary change region in Control Panel.
|
If you are in Russia or Belarus temporary change region in Control Panel.
|
||||||
|
|
||||||
### blockcheck
|
### blockcheck
|
||||||
|
@ -159,6 +159,7 @@ _windivert 2.2.2-A_, который идет в поставке zapret.
|
|||||||
и заменить эти 2 файла.
|
и заменить эти 2 файла.
|
||||||
В [zapret-win-bundle](https://github.com/bol-van/zapret-win-bundle) есть отдельных 2 места, где находится **winws** : [_zapret-winws_](https://github.com/bol-van/zapret-win-bundle/tree/master/zapret-winws) и [_blockcheck/zapret/nfq_](https://github.com/bol-van/zapret-win-bundle/tree/master/blockcheck).
|
В [zapret-win-bundle](https://github.com/bol-van/zapret-win-bundle) есть отдельных 2 места, где находится **winws** : [_zapret-winws_](https://github.com/bol-van/zapret-win-bundle/tree/master/zapret-winws) и [_blockcheck/zapret/nfq_](https://github.com/bol-van/zapret-win-bundle/tree/master/blockcheck).
|
||||||
Надо менять в обоих местах.
|
Надо менять в обоих местах.
|
||||||
|
Альтернативный вариант при использовании win bundle - запустить `win7\install_win7.cmd`
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> Этот вариант проверен и должен работать. Тем не менее патч 10 летней давности, который включает SHA256 сигнатуры, все еще необходим.
|
> Этот вариант проверен и должен работать. Тем не менее патч 10 летней давности, который включает SHA256 сигнатуры, все еще необходим.
|
||||||
|
BIN
files/fake/discord-ip-discovery-with-port.bin
Normal file
BIN
files/fake/discord-ip-discovery-with-port.bin
Normal file
Binary file not shown.
BIN
files/fake/discord-ip-discovery-without-port.bin
Normal file
BIN
files/fake/discord-ip-discovery-without-port.bin
Normal file
Binary file not shown.
BIN
files/fake/isakmp_initiator_request.bin
Normal file
BIN
files/fake/isakmp_initiator_request.bin
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
files/fake/stun.bin
Normal file
BIN
files/fake/stun.bin
Normal file
Binary file not shown.
Binary file not shown.
22
init.d/custom.d.examples.linux/10-keenetic-udp-fix
Normal file
22
init.d/custom.d.examples.linux/10-keenetic-udp-fix
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# This script fixes keenetic issue with nfqws generated udp packets
|
||||||
|
# Keenetic uses proprietary ndmmark and does not masquerade without this mark
|
||||||
|
# If not masqueraded packets go to WAN with LAN IP and get dropped by ISP
|
||||||
|
|
||||||
|
# It's advised to set IFACE_WAN in config
|
||||||
|
|
||||||
|
zapret_custom_firewall()
|
||||||
|
{
|
||||||
|
# $1 - 1 - add, 0 - stop
|
||||||
|
|
||||||
|
local wan wanif rule
|
||||||
|
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
|
# use IFACE_WAN if defined. if not - search for interfaces with default route.
|
||||||
|
wanif=${IFACE_WAN:-$(sed -nre 's/^([^\t]+)\t00000000\t[0-9A-F]{8}\t[0-9A-F]{4}\t[0-9]+\t[0-9]+\t[0-9]+\t00000000.*$/\1/p' /proc/net/route | sort -u | xargs)}
|
||||||
|
for wan in $wanif; do
|
||||||
|
rule="-o $wan -p udp -m mark --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||||
|
ipt_print_op $1 "$rule" "keenetic udp fix"
|
||||||
|
ipt_add_del $1 POSTROUTING -t nat $rule -j MASQUERADE
|
||||||
|
done
|
||||||
|
}
|
||||||
|
}
|
66
init.d/custom.d.examples.linux/20-fw-extra
Normal file
66
init.d/custom.d.examples.linux/20-fw-extra
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# this custom script runs standard mode with extra firewall rules
|
||||||
|
|
||||||
|
# config: use TPWS_ENABLE_OVERRIDE, NFQWS_ENABLE_OVERRIDE to enable standard mode daemons
|
||||||
|
# standard and override switches cannot be enabled simultaneously !
|
||||||
|
|
||||||
|
TPWS_ENABLE_OVERRIDE=${TPWS_ENABLE_OVERRIDE:-0}
|
||||||
|
NFQWS_ENABLE_OVERRIDE=${NFQWS_ENABLE_OVERRIDE:-0}
|
||||||
|
|
||||||
|
# config: some if these values must be set in config. not setting any of these makes this script meaningless.
|
||||||
|
# pre vars put ipt/nft code to the rule beginning
|
||||||
|
#FW_EXTRA_PRE_TPWS_IPT=
|
||||||
|
#FW_EXTRA_PRE_TPWS_NFT=
|
||||||
|
#FW_EXTRA_PRE_NFQWS_IPT="-m mark --mark 0x10000000/0x10000000"
|
||||||
|
#FW_EXTRA_PRE_NFQWS_NFT="mark and 0x10000000 != 0"
|
||||||
|
# post vars put ipt/nft code to the rule end
|
||||||
|
#FW_EXTRA_POST_TPWS_IPT=
|
||||||
|
#FW_EXTRA_POST_TPWS_NFT=
|
||||||
|
#FW_EXTRA_POST_NFQWS_IPT=
|
||||||
|
#FW_EXTRA_POST_NFQWS_NFT=
|
||||||
|
|
||||||
|
check_std_intersect()
|
||||||
|
{
|
||||||
|
[ "$TPWS_ENABLE_OVERRIDE" = 1 -a "$TPWS_ENABLE" = 1 ] && {
|
||||||
|
echo "ERROR ! both TPWS_ENABLE_OVERRIDE and TPWS_ENABLE are enabled"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
[ "$NFQWS_ENABLE_OVERRIDE" = 1 -a "$NFQWS_ENABLE" = 1 ] && {
|
||||||
|
echo "ERROR ! both NFQWS_ENABLE_OVERRIDE and NFQWS_ENABLE are enabled"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
zapret_custom_daemons()
|
||||||
|
{
|
||||||
|
# $1 - 1 - add, 0 - stop
|
||||||
|
|
||||||
|
check_std_intersect || return
|
||||||
|
|
||||||
|
local TPWS_SOCKS_ENABLE=0 TPWS_ENABLE=$TPWS_ENABLE_OVERRIDE NFQWS_ENABLE=$NFQWS_ENABLE_OVERRIDE
|
||||||
|
standard_mode_daemons "$1"
|
||||||
|
}
|
||||||
|
zapret_custom_firewall()
|
||||||
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
|
check_std_intersect || return
|
||||||
|
|
||||||
|
local FW_EXTRA_PRE FW_EXTRA_POST TPWS_ENABLE=$TPWS_ENABLE_OVERRIDE NFQWS_ENABLE=$NFQWS_ENABLE_OVERRIDE
|
||||||
|
FW_EXTRA_PRE="$FW_EXTRA_PRE_TPWS_IPT" FW_EXTRA_POST="$FW_EXTRA_POST_TPWS_IPT"
|
||||||
|
zapret_do_firewall_standard_tpws_rules_ipt $1
|
||||||
|
FW_EXTRA_PRE="$FW_EXTRA_PRE_NFQWS_IPT" FW_EXTRA_POST="$FW_EXTRA_POST_NFQWS_IPT"
|
||||||
|
zapret_do_firewall_standard_nfqws_rules_ipt $1
|
||||||
|
}
|
||||||
|
zapret_custom_firewall_nft()
|
||||||
|
{
|
||||||
|
# stop logic is not required
|
||||||
|
|
||||||
|
check_std_intersect || return
|
||||||
|
|
||||||
|
local FW_EXTRA_PRE FW_EXTRA_POST TPWS_ENABLE=$TPWS_ENABLE_OVERRIDE NFQWS_ENABLE=$NFQWS_ENABLE_OVERRIDE
|
||||||
|
FW_EXTRA_PRE="$FW_EXTRA_PRE_TPWS_NFT" FW_EXTRA_POST="$FW_EXTRA_POST_TPWS_NFT"
|
||||||
|
zapret_apply_firewall_standard_tpws_rules_nft
|
||||||
|
FW_EXTRA_PRE="$FW_EXTRA_PRE_NFQWS_NFT" FW_EXTRA_POST="$FW_EXTRA_POST_NFQWS_NFT"
|
||||||
|
zapret_apply_firewall_standard_nfqws_rules_nft
|
||||||
|
}
|
@ -8,9 +8,9 @@ alloc_qnum QNUM_DHT4ALL
|
|||||||
|
|
||||||
zapret_custom_daemons()
|
zapret_custom_daemons()
|
||||||
{
|
{
|
||||||
# stop logic is managed by procd
|
# $1 - 1 - add, 0 - stop
|
||||||
|
|
||||||
local opt="--qnum=$QNUM_DHT4ALL $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DHT"
|
local opt="--qnum=$QNUM_DHT4ALL $NFQWS_OPT_DESYNC_DHT"
|
||||||
do_nfqws $1 $DNUM_DHT4ALL "$opt"
|
do_nfqws $1 $DNUM_DHT4ALL "$opt"
|
||||||
}
|
}
|
||||||
zapret_custom_firewall()
|
zapret_custom_firewall()
|
74
init.d/custom.d.examples.linux/50-nfqws-ipset
Normal file
74
init.d/custom.d.examples.linux/50-nfqws-ipset
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
# this custom script demonstrates how to launch extra nfqws instance limited by ipset. ipv4 only.
|
||||||
|
|
||||||
|
# can override in config :
|
||||||
|
NFQWS_OPT_DESYNC_NFQWS_MY1="${NFQWS_OPT_DESYNC_NFQWS_MY1:---dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-any-protocol}"
|
||||||
|
NFQWS_MY1_PORTS=${NFQWS_MY1_PORTS:-6000-6009}
|
||||||
|
NFQWS_MY1_SUBNETS="${NFQWS_MY1_SUBNETS:-34.0.48.0/21 34.0.56.0/23 34.0.59.0/24 34.0.60.0/24 34.0.62.0/23}"
|
||||||
|
|
||||||
|
alloc_dnum DNUM_NFQWS_MY1
|
||||||
|
alloc_qnum QNUM_NFQWS_MY1
|
||||||
|
NFQWS_MY1_SET_NAME=my1nfqws4
|
||||||
|
|
||||||
|
zapret_custom_daemons()
|
||||||
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
|
local opt="--qnum=$QNUM_NFQWS_MY1 $NFQWS_OPT_DESYNC_NFQWS_MY1"
|
||||||
|
do_nfqws $1 $DNUM_NFQWS_MY1 "$opt"
|
||||||
|
}
|
||||||
|
|
||||||
|
zapret_custom_firewall()
|
||||||
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
|
local f
|
||||||
|
local first_packets_only="$ipt_connbytes 1:3"
|
||||||
|
local NFQWS_MY1_PORTS_IPT=$(replace_char - : $NFQWS_MY1_PORTS)
|
||||||
|
local dest_set="-m set --match-set $NFQWS_MY1_SET_NAME dst"
|
||||||
|
local subnet
|
||||||
|
|
||||||
|
local DISABLE_IPV6=1
|
||||||
|
|
||||||
|
[ "$1" = 1 ] && {
|
||||||
|
ipset create $NFQWS_MY1_SET_NAME hash:net hashsize 8192 maxelem 4096 2>/dev/null
|
||||||
|
ipset flush $NFQWS_MY1_SET_NAME
|
||||||
|
for subnet in $NFQWS_MY1_SUBNETS; do
|
||||||
|
echo add $NFQWS_MY1_SET_NAME $subnet
|
||||||
|
done | ipset -! restore
|
||||||
|
}
|
||||||
|
|
||||||
|
f="-p udp -m multiport --dports $NFQWS_MY1_PORTS_IPT"
|
||||||
|
fw_nfqws_post $1 "$f $first_packets_only $dest_set" "" $QNUM_NFQWS_MY1
|
||||||
|
|
||||||
|
[ "$1" = 1 ] || {
|
||||||
|
ipset destroy $NFQWS_MY1_SET_NAME 2>/dev/null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zapret_custom_firewall_nft()
|
||||||
|
{
|
||||||
|
# stop logic is not required
|
||||||
|
|
||||||
|
local f
|
||||||
|
local first_packets_only="$nft_connbytes 1-3"
|
||||||
|
local dest_set="ip daddr @$NFQWS_MY1_SET_NAME"
|
||||||
|
local subnets
|
||||||
|
|
||||||
|
local DISABLE_IPV6=1
|
||||||
|
|
||||||
|
make_comma_list subnets $NFQWS_MY1_SUBNETS
|
||||||
|
nft_create_set $NFQWS_MY1_SET_NAME "type ipv4_addr; size 4096; auto-merge; flags interval;"
|
||||||
|
nft_flush_set $NFQWS_MY1_SET_NAME
|
||||||
|
nft_add_set_element $NFQWS_MY1_SET_NAME "$subnets"
|
||||||
|
|
||||||
|
f="udp dport {$NFQWS_MY1_PORTS}"
|
||||||
|
nft_fw_nfqws_post "$f $first_packets_only $dest_set" "" $QNUM_NFQWS_MY1
|
||||||
|
}
|
||||||
|
|
||||||
|
zapret_custom_firewall_nft_flush()
|
||||||
|
{
|
||||||
|
# this function is called after all nft fw rules are deleted
|
||||||
|
# however sets are not deleted. it's desired to clear sets here.
|
||||||
|
|
||||||
|
nft_del_set $NFQWS_MY1_SET_NAME 2>/dev/null
|
||||||
|
}
|
89
init.d/custom.d.examples.linux/50-tpws-ipset
Normal file
89
init.d/custom.d.examples.linux/50-tpws-ipset
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
# this custom script demonstrates how to launch extra tpws instance limited by ipset
|
||||||
|
|
||||||
|
# can override in config :
|
||||||
|
TPWS_MY1_OPT="${TPWS_MY1_OPT:---oob --split-pos=midsld}"
|
||||||
|
TPWS_MY1_PORTS=${TPWS_MY1_PORTS:-$TPWS_PORTS}
|
||||||
|
TPWS_MY1_SUBNETS4="${TPWS_MY1_SUBNETS4:-142.250.0.0/15 64.233.160.0/19 172.217.0.0/16 173.194.0.0/16 108.177.0.0/17 74.125.0.0/16 209.85.128.0/17 216.58.192.0/19}"
|
||||||
|
TPWS_MY1_SUBNETS6="${TPWS_MY1_SUBNETS6:-2607:F8B0::/32 2a00:1450:4000::/37}"
|
||||||
|
|
||||||
|
TPWS_MY1_IPSET_SIZE=${TPWS_MY1_IPSET_SIZE:-4096}
|
||||||
|
TPWS_MY1_IPSET_OPT="${TPWS_MY1_IPSET_OPT:-hash:net hashsize 8192 maxelem $TPWS_MY1_IPSET_SIZE}"
|
||||||
|
|
||||||
|
alloc_dnum DNUM_TPWS_MY1
|
||||||
|
alloc_tpws_port PORT_TPWS_MY1
|
||||||
|
TPWS_MY1_NAME4=my1tpws4
|
||||||
|
TPWS_MY1_NAME6=my1tpws6
|
||||||
|
|
||||||
|
zapret_custom_daemons()
|
||||||
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
|
local opt="--port=$PORT_TPWS_MY1 $TPWS_MY1_OPT"
|
||||||
|
do_tpws $1 $DNUM_TPWS_MY1 "$opt"
|
||||||
|
}
|
||||||
|
|
||||||
|
zapret_custom_firewall()
|
||||||
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
|
local f4 f6 subnet
|
||||||
|
local PORTS_IPT=$(replace_char - : $TPWS_MY1_PORTS)
|
||||||
|
local dest_set="-m set --match-set $TPWS_MY1_NAME4 dst"
|
||||||
|
|
||||||
|
[ "$1" = 1 -a "$DISABLE_IPV4" != 1 ] && {
|
||||||
|
ipset create $TPWS_MY1_NAME4 $TPWS_MY1_IPSET_OPT family inet 2>/dev/null
|
||||||
|
ipset flush $TPWS_MY1_NAME4
|
||||||
|
for subnet in $TPWS_MY1_SUBNETS4; do
|
||||||
|
echo add $TPWS_MY1_NAME4 $subnet
|
||||||
|
done | ipset -! restore
|
||||||
|
}
|
||||||
|
[ "$1" = 1 -a "$DISABLE_IPV6" != 1 ] && {
|
||||||
|
ipset create $TPWS_MY1_NAME6 $TPWS_MY1_IPSET_OPT family inet6 2>/dev/null
|
||||||
|
ipset flush $TPWS_MY1_NAME6
|
||||||
|
for subnet in $TPWS_MY1_SUBNETS6; do
|
||||||
|
echo add $TPWS_MY1_NAME6 $subnet
|
||||||
|
done | ipset -! restore
|
||||||
|
}
|
||||||
|
|
||||||
|
f4="-p tcp -m multiport --dports $PORTS_IPT -m set --match-set"
|
||||||
|
f6="$f4 $TPWS_MY1_NAME6 dst"
|
||||||
|
f4="$f4 $TPWS_MY1_NAME4 dst"
|
||||||
|
fw_tpws $1 "$f4" "$f6" $PORT_TPWS_MY1
|
||||||
|
|
||||||
|
[ "$1" = 1 ] || {
|
||||||
|
ipset destroy $TPWS_MY1_NAME4 2>/dev/null
|
||||||
|
ipset destroy $TPWS_MY1_NAME6 2>/dev/null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zapret_custom_firewall_nft()
|
||||||
|
{
|
||||||
|
local f4 f6 subnet
|
||||||
|
|
||||||
|
[ "$DISABLE_IPV4" != 1 ] && {
|
||||||
|
make_comma_list subnets $TPWS_MY1_SUBNETS4
|
||||||
|
nft_create_set $TPWS_MY1_NAME4 "type ipv4_addr; size $TPWS_MY1_IPSET_SIZE; auto-merge; flags interval;"
|
||||||
|
nft_flush_set $TPWS_MY1_NAME4
|
||||||
|
nft_add_set_element $TPWS_MY1_NAME4 "$subnets"
|
||||||
|
}
|
||||||
|
[ "$DISABLE_IPV6" != 1 ] && {
|
||||||
|
make_comma_list subnets $TPWS_MY1_SUBNETS6
|
||||||
|
nft_create_set $TPWS_MY1_NAME6 "type ipv6_addr; size $TPWS_MY1_IPSET_SIZE; auto-merge; flags interval;"
|
||||||
|
nft_flush_set $TPWS_MY1_NAME6
|
||||||
|
nft_add_set_element $TPWS_MY1_NAME6 "$subnets"
|
||||||
|
}
|
||||||
|
|
||||||
|
f4="tcp dport {$TPWS_MY1_PORTS}"
|
||||||
|
f6="$f4 ip6 daddr @$TPWS_MY1_NAME6"
|
||||||
|
f4="$f4 ip daddr @$TPWS_MY1_NAME4"
|
||||||
|
nft_fw_tpws "$f4" "$f6" $PORT_TPWS_MY1
|
||||||
|
}
|
||||||
|
|
||||||
|
zapret_custom_firewall_nft_flush()
|
||||||
|
{
|
||||||
|
# this function is called after all nft fw rules are deleted
|
||||||
|
# however sets are not deleted. it's desired to clear sets here.
|
||||||
|
|
||||||
|
nft_del_set $TPWS_MY1_NAME4 2>/dev/null
|
||||||
|
nft_del_set $TPWS_MY1_NAME6 2>/dev/null
|
||||||
|
}
|
30
init.d/custom.d.examples.linux/50-wg4all
Normal file
30
init.d/custom.d.examples.linux/50-wg4all
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# this custom script runs desync to all wireguard handshake initiation packets
|
||||||
|
|
||||||
|
# can override in config :
|
||||||
|
NFQWS_OPT_DESYNC_WG="${NFQWS_OPT_DESYNC_WG:---dpi-desync=fake}"
|
||||||
|
|
||||||
|
alloc_dnum DNUM_WG4ALL
|
||||||
|
alloc_qnum QNUM_WG4ALL
|
||||||
|
|
||||||
|
zapret_custom_daemons()
|
||||||
|
{
|
||||||
|
# $1 - 1 - add, 0 - stop
|
||||||
|
|
||||||
|
local opt="--qnum=$QNUM_WG4ALL $NFQWS_OPT_DESYNC_WG"
|
||||||
|
do_nfqws $1 $DNUM_WG4ALL "$opt"
|
||||||
|
}
|
||||||
|
# size = 156 (8 udp header + 148 payload) && payload starts with 0x01000000
|
||||||
|
zapret_custom_firewall()
|
||||||
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
|
local f='-p udp -m u32 --u32'
|
||||||
|
fw_nfqws_post $1 "$f 0>>22&0x3C@4>>16=0x9c&&0>>22&0x3C@8=0x01000000" "$f 44>>16=0x9c&&48=0x01000000" $QNUM_WG4ALL
|
||||||
|
}
|
||||||
|
zapret_custom_firewall_nft()
|
||||||
|
{
|
||||||
|
# stop logic is not required
|
||||||
|
|
||||||
|
local f="udp length 156 @th,64,32 0x01000000"
|
||||||
|
nft_fw_nfqws_post "$f" "$f" $QNUM_WG4ALL
|
||||||
|
}
|
@ -1,38 +0,0 @@
|
|||||||
# this custom script runs desync to DHT packets with udp payload length 101..399 , without ipset/hostlist filtering
|
|
||||||
|
|
||||||
# can override in config :
|
|
||||||
NFQWS_OPT_DESYNC_DHT="${NFQWS_OPT_DESYNC_DHT:---dpi-desync=tamper}"
|
|
||||||
|
|
||||||
alloc_dnum DNUM_DHT4ALL
|
|
||||||
alloc_qnum QNUM_DHT4ALL
|
|
||||||
|
|
||||||
zapret_custom_daemons()
|
|
||||||
{
|
|
||||||
# stop logic is managed by procd
|
|
||||||
|
|
||||||
local opt="--qnum=$QNUM_DHT4ALL $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DHT"
|
|
||||||
run_daemon $DNUM_DHT4ALL $NFQWS "$opt"
|
|
||||||
}
|
|
||||||
zapret_custom_firewall()
|
|
||||||
{
|
|
||||||
# $1 - 1 - run, 0 - stop
|
|
||||||
|
|
||||||
local f uf4 uf6
|
|
||||||
local first_packet_only="$ipt_connbytes 1:1"
|
|
||||||
|
|
||||||
f='-p udp -m length --length 109:407 -m u32 --u32'
|
|
||||||
uf4='0>>22&0x3C@8>>16=0x6431'
|
|
||||||
uf6='48>>16=0x6431'
|
|
||||||
fw_nfqws_post $1 "$f $uf4 $first_packet_only" "$f $uf6 $first_packet_only" $QNUM_DHT4ALL
|
|
||||||
|
|
||||||
}
|
|
||||||
zapret_custom_firewall_nft()
|
|
||||||
{
|
|
||||||
# stop logic is not required
|
|
||||||
|
|
||||||
local f
|
|
||||||
local first_packet_only="$nft_connbytes 1"
|
|
||||||
|
|
||||||
f="meta length 109-407 meta l4proto udp @th,64,16 0x6431"
|
|
||||||
nft_fw_nfqws_post "$f $first_packet_only" "$f $first_packet_only" $QNUM_DHT4ALL
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
@ -10,6 +10,7 @@ ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
|
|||||||
. "$ZAPRET_BASE/common/ipt.sh"
|
. "$ZAPRET_BASE/common/ipt.sh"
|
||||||
. "$ZAPRET_BASE/common/nft.sh"
|
. "$ZAPRET_BASE/common/nft.sh"
|
||||||
. "$ZAPRET_BASE/common/linux_fw.sh"
|
. "$ZAPRET_BASE/common/linux_fw.sh"
|
||||||
|
. "$ZAPRET_BASE/common/linux_daemons.sh"
|
||||||
. "$ZAPRET_BASE/common/list.sh"
|
. "$ZAPRET_BASE/common/list.sh"
|
||||||
. "$ZAPRET_BASE/common/custom.sh"
|
. "$ZAPRET_BASE/common/custom.sh"
|
||||||
CUSTOM_DIR="$ZAPRET_RW/init.d/openwrt"
|
CUSTOM_DIR="$ZAPRET_RW/init.d/openwrt"
|
||||||
@ -24,15 +25,8 @@ CUSTOM_DIR="$ZAPRET_RW/init.d/openwrt"
|
|||||||
|
|
||||||
TPWS_LOCALHOST4=127.0.0.127
|
TPWS_LOCALHOST4=127.0.0.127
|
||||||
|
|
||||||
# max wait time for the link local ipv6 on the LAN interface
|
|
||||||
LINKLOCAL_WAIT_SEC=5
|
|
||||||
|
|
||||||
IPSET_CR="$ZAPRET_BASE/ipset/create_ipset.sh"
|
IPSET_CR="$ZAPRET_BASE/ipset/create_ipset.sh"
|
||||||
|
|
||||||
IPSET_EXCLUDE="-m set ! --match-set nozapret"
|
|
||||||
IPSET_EXCLUDE6="-m set ! --match-set nozapret6"
|
|
||||||
|
|
||||||
|
|
||||||
# can be multiple ipv6 outgoing interfaces
|
# can be multiple ipv6 outgoing interfaces
|
||||||
# uplink from isp, tunnelbroker, vpn, ...
|
# uplink from isp, tunnelbroker, vpn, ...
|
||||||
# want them all. who knows what's the real one that blocks sites
|
# want them all. who knows what's the real one that blocks sites
|
||||||
|
@ -81,6 +81,10 @@ run_tpws()
|
|||||||
}
|
}
|
||||||
run_daemon $1 "$TPWS" "$OPT $2"
|
run_daemon $1 "$TPWS" "$OPT $2"
|
||||||
}
|
}
|
||||||
|
do_tpws()
|
||||||
|
{
|
||||||
|
[ "$1" = 0 ] || { shift; run_tpws "$@"; }
|
||||||
|
}
|
||||||
run_tpws_socks()
|
run_tpws_socks()
|
||||||
{
|
{
|
||||||
[ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] && return 0
|
[ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] && return 0
|
||||||
@ -90,13 +94,10 @@ run_tpws_socks()
|
|||||||
tpws_apply_socks_binds opt
|
tpws_apply_socks_binds opt
|
||||||
run_daemon $1 "$TPWS" "$opt $2"
|
run_daemon $1 "$TPWS" "$opt $2"
|
||||||
}
|
}
|
||||||
|
do_tpws_socks()
|
||||||
stop_tpws()
|
|
||||||
{
|
{
|
||||||
stop_daemon $1 "$TPWS"
|
[ "$1" = 0 ] || { shift; run_tpws_socks "$@"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
tpws_apply_socks_binds()
|
tpws_apply_socks_binds()
|
||||||
{
|
{
|
||||||
local o
|
local o
|
||||||
@ -105,39 +106,27 @@ tpws_apply_socks_binds()
|
|||||||
[ "$DISABLE_IPV6" = "1" ] || o="$o --bind-addr=::1"
|
[ "$DISABLE_IPV6" = "1" ] || o="$o --bind-addr=::1"
|
||||||
|
|
||||||
for lan in $OPENWRT_LAN; do
|
for lan in $OPENWRT_LAN; do
|
||||||
network_get_device DEVICE $lan
|
network_get_device DEVICE $lan
|
||||||
[ -n "$DEVICE" ] || continue
|
[ -n "$DEVICE" ] || continue
|
||||||
[ "$DISABLE_IPV4" = "1" ] || o="$o --bind-iface4=$DEVICE $TPWS_WAIT"
|
[ "$DISABLE_IPV4" = "1" ] || o="$o --bind-iface4=$DEVICE $TPWS_WAIT"
|
||||||
[ "$DISABLE_IPV6" = "1" ] || o="$o --bind-iface6=$DEVICE --bind-linklocal=unwanted $TPWS_WAIT_SOCKS6"
|
[ "$DISABLE_IPV6" = "1" ] || o="$o --bind-iface6=$DEVICE --bind-linklocal=unwanted $TPWS_WAIT_SOCKS6"
|
||||||
done
|
done
|
||||||
eval $1="\"\$$1 $o\""
|
eval $1="\"\$$1 $o\""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run_nfqws()
|
||||||
standard_mode_daemons()
|
|
||||||
{
|
{
|
||||||
local opt
|
run_daemon $1 "$NFQWS" "$NFQWS_OPT_BASE $2"
|
||||||
[ "$TPWS_ENABLE" = 1 ] && check_bad_ws_options 1 "$TPWS_OPT" && {
|
}
|
||||||
opt="--port=$TPPORT $TPWS_OPT"
|
do_nfqws()
|
||||||
filter_apply_hostlist_target opt
|
{
|
||||||
run_tpws 1 "$opt"
|
[ "$1" = 0 ] || { shift; run_nfqws "$@"; }
|
||||||
}
|
|
||||||
[ "$TPWS_SOCKS_ENABLE" = 1 ] && {
|
|
||||||
opt="--port=$TPPORT_SOCKS $TPWS_SOCKS_OPT"
|
|
||||||
filter_apply_hostlist_target opt
|
|
||||||
run_tpws_socks 2 "$opt"
|
|
||||||
}
|
|
||||||
[ "$NFQWS_ENABLE" = 1 ] && check_bad_ws_options 1 "$NFQWS_OPT" && {
|
|
||||||
opt="--qnum=$QNUM $NFQWS_OPT_BASE $NFQWS_OPT"
|
|
||||||
filter_apply_hostlist_target opt
|
|
||||||
run_daemon 3 "$NFQWS" "$opt"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
start_daemons_procd()
|
start_daemons_procd()
|
||||||
{
|
{
|
||||||
standard_mode_daemons
|
standard_mode_daemons 1
|
||||||
custom_runner zapret_custom_daemons
|
custom_runner zapret_custom_daemons 1
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -21,4 +21,4 @@ pfctl -d ; pfctl -e
|
|||||||
ipfw delete 100
|
ipfw delete 100
|
||||||
ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted not sockarg
|
ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted not sockarg
|
||||||
pkill ^dvtws$
|
pkill ^dvtws$
|
||||||
dvtws --daemon --port 989 --dpi-desync=split2
|
dvtws --daemon --port 989 --dpi-desync=multisplit
|
||||||
|
65
init.d/systemd/nfqws@.service
Normal file
65
init.d/systemd/nfqws@.service
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
# Example systemd service unit for nfqws. Adjust for your installation.
|
||||||
|
|
||||||
|
# WARNING ! This unit requires to compile nfqws using `make systemd`
|
||||||
|
# WARNING ! This makefile target enabled special systemd notify support.
|
||||||
|
|
||||||
|
# PREPARE
|
||||||
|
# install build depends
|
||||||
|
# make -C /opt/zapret systemd
|
||||||
|
# cp nfqws@service /lib/systemd/system
|
||||||
|
# systemctl daemon-reload
|
||||||
|
|
||||||
|
# MANAGE INSTANCE
|
||||||
|
# prepare /etc/zapret/nfqws1.conf with nfqws parameters
|
||||||
|
# systemctl start nfqws@nfqws1
|
||||||
|
# systemctl status nfqws@nfqws1
|
||||||
|
# systemctl restart nfqws@nfqws1
|
||||||
|
# systemctl enable nfqws@nfqws1
|
||||||
|
# systemctl disable nfqws@nfqws1
|
||||||
|
# systemctl stop nfqws@nfqws1
|
||||||
|
|
||||||
|
# DELETE
|
||||||
|
# rm /lib/systemd/system/nfqws@.service
|
||||||
|
# systemctl daemon-reload
|
||||||
|
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=notify
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
ExecSearchPath=/opt/zapret/binaries/my
|
||||||
|
ExecStart=nfqws @${CONFIG_DIR}/${INSTANCE}.conf
|
||||||
|
Environment=CONFIG_DIR=/etc/zapret
|
||||||
|
Environment=INSTANCE=%i
|
||||||
|
|
||||||
|
RestrictAddressFamilies=AF_NETLINK AF_UNIX AF_INET6 AF_INET
|
||||||
|
|
||||||
|
LockPersonality=true
|
||||||
|
MemoryDenyWriteExecute=true
|
||||||
|
PrivateDevices=true
|
||||||
|
PrivateMounts=true
|
||||||
|
PrivateTmp=true
|
||||||
|
ProcSubset=pid
|
||||||
|
ProtectClock=true
|
||||||
|
ProtectControlGroups=true
|
||||||
|
ProtectHome=true
|
||||||
|
ProtectHostname=true
|
||||||
|
ProtectKernelLogs=true
|
||||||
|
ProtectKernelModules=true
|
||||||
|
ProtectKernelTunables=true
|
||||||
|
ProtectProc=invisible
|
||||||
|
ProtectSystem=full
|
||||||
|
RemoveIPC=true
|
||||||
|
RestrictNamespaces=true
|
||||||
|
RestrictRealtime=true
|
||||||
|
RestrictSUIDSGID=true
|
||||||
|
SystemCallArchitectures=native
|
||||||
|
SystemCallFilter=@system-service
|
||||||
|
SystemCallFilter=~@resources
|
||||||
|
UMask=0077
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
63
init.d/systemd/tpws@.service
Normal file
63
init.d/systemd/tpws@.service
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
# Example systemd service unit for tpws. Adjust for your installation.
|
||||||
|
|
||||||
|
# WARNING ! This unit requires to compile tpws using `make systemd`
|
||||||
|
# WARNING ! This makefile target enabled special systemd notify support.
|
||||||
|
|
||||||
|
# PREPARE
|
||||||
|
# install build depends
|
||||||
|
# make -C /opt/zapret systemd
|
||||||
|
# cp tpws@service /lib/systemd/system
|
||||||
|
# systemctl daemon-reload
|
||||||
|
|
||||||
|
# MANAGE INSTANCE
|
||||||
|
# prepare /etc/zapret/tpws1.conf with tpws parameters
|
||||||
|
# systemctl start tpws@tpws1
|
||||||
|
# systemctl status tpws@tpws1
|
||||||
|
# systemctl restart tpws@tpws1
|
||||||
|
# systemctl enable tpws@tpws1
|
||||||
|
# systemctl disable tpws@tpws1
|
||||||
|
# systemctl stop tpws@tpws1
|
||||||
|
|
||||||
|
# DELETE
|
||||||
|
# rm /lib/systemd/system/tpws@.service
|
||||||
|
# systemctl daemon-reload
|
||||||
|
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=notify
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
ExecSearchPath=/opt/zapret/binaries/my
|
||||||
|
ExecStart=tpws @${CONFIG_DIR}/${INSTANCE}.conf
|
||||||
|
Environment=CONFIG_DIR=/etc/zapret
|
||||||
|
Environment=INSTANCE=%i
|
||||||
|
|
||||||
|
RestrictAddressFamilies=AF_NETLINK AF_UNIX AF_INET6 AF_INET
|
||||||
|
|
||||||
|
LockPersonality=true
|
||||||
|
MemoryDenyWriteExecute=true
|
||||||
|
PrivateDevices=true
|
||||||
|
PrivateMounts=true
|
||||||
|
PrivateTmp=true
|
||||||
|
ProcSubset=pid
|
||||||
|
ProtectClock=true
|
||||||
|
ProtectControlGroups=true
|
||||||
|
ProtectHome=true
|
||||||
|
ProtectHostname=true
|
||||||
|
ProtectKernelLogs=true
|
||||||
|
ProtectKernelModules=true
|
||||||
|
ProtectProc=invisible
|
||||||
|
ProtectSystem=full
|
||||||
|
RemoveIPC=true
|
||||||
|
RestrictNamespaces=true
|
||||||
|
RestrictRealtime=true
|
||||||
|
RestrictSUIDSGID=true
|
||||||
|
SystemCallArchitectures=native
|
||||||
|
SystemCallFilter=@system-service
|
||||||
|
UMask=0077
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
File diff suppressed because one or more lines are too long
@ -10,6 +10,7 @@ ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
|
|||||||
. "$ZAPRET_BASE/common/ipt.sh"
|
. "$ZAPRET_BASE/common/ipt.sh"
|
||||||
. "$ZAPRET_BASE/common/nft.sh"
|
. "$ZAPRET_BASE/common/nft.sh"
|
||||||
. "$ZAPRET_BASE/common/linux_fw.sh"
|
. "$ZAPRET_BASE/common/linux_fw.sh"
|
||||||
|
. "$ZAPRET_BASE/common/linux_daemons.sh"
|
||||||
. "$ZAPRET_BASE/common/list.sh"
|
. "$ZAPRET_BASE/common/list.sh"
|
||||||
. "$ZAPRET_BASE/common/custom.sh"
|
. "$ZAPRET_BASE/common/custom.sh"
|
||||||
CUSTOM_DIR="$ZAPRET_RW/init.d/sysv"
|
CUSTOM_DIR="$ZAPRET_RW/init.d/sysv"
|
||||||
@ -89,20 +90,13 @@ TPWS_WAIT_SOCKS6="$TPWS_WAIT --bind-wait-ip-linklocal=30"
|
|||||||
# first wait for lan to ifup, then wait for bind-wait-ip-linklocal seconds for link local address and bind-wait-ip for any ipv6 as the worst case
|
# first wait for lan to ifup, then wait for bind-wait-ip-linklocal seconds for link local address and bind-wait-ip for any ipv6 as the worst case
|
||||||
TPWS_OPT_BASE6_PRE="--bind-linklocal=prefer $TPWS_WAIT --bind-wait-ip-linklocal=3"
|
TPWS_OPT_BASE6_PRE="--bind-linklocal=prefer $TPWS_WAIT --bind-wait-ip-linklocal=3"
|
||||||
|
|
||||||
# max wait time for the link local ipv6 on the LAN interface
|
|
||||||
LINKLOCAL_WAIT_SEC=5
|
|
||||||
|
|
||||||
IPSET_EXCLUDE="-m set ! --match-set nozapret"
|
|
||||||
IPSET_EXCLUDE6="-m set ! --match-set nozapret6"
|
|
||||||
|
|
||||||
|
|
||||||
dnat6_target()
|
dnat6_target()
|
||||||
{
|
{
|
||||||
_dnat6_target "$@"
|
_dnat6_target "$@"
|
||||||
}
|
}
|
||||||
set_route_localnet()
|
set_route_localnet()
|
||||||
{
|
{
|
||||||
_set_route_localnet $1 "$IFACE_LAN"
|
_set_route_localnet $1 $IFACE_LAN
|
||||||
}
|
}
|
||||||
|
|
||||||
fw_nfqws_post4()
|
fw_nfqws_post4()
|
||||||
@ -167,9 +161,15 @@ run_daemon()
|
|||||||
# use $PIDDIR/$DAEMONBASE$1.pid as pidfile
|
# use $PIDDIR/$DAEMONBASE$1.pid as pidfile
|
||||||
|
|
||||||
local DAEMONBASE="$(basename "$2")"
|
local DAEMONBASE="$(basename "$2")"
|
||||||
local PIDFILE=$PIDDIR/$DAEMONBASE$1.pid
|
local PID= PIDFILE=$PIDDIR/$DAEMONBASE$1.pid
|
||||||
echo "Starting daemon $1: $2 $3"
|
echo "Starting daemon $1: $2 $3"
|
||||||
if [ -f "$PIDFILE" ] && pgrep -F "$PIDFILE" "$DAEMONBASE" >/dev/null; then
|
|
||||||
|
[ -f "$PIDFILE" ] && {
|
||||||
|
read PID <"$PIDFILE"
|
||||||
|
[ -d "/proc/$PID" ] || PID=
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -n "$PID" ]; then
|
||||||
echo already running
|
echo already running
|
||||||
else
|
else
|
||||||
"$2" $3 >/dev/null &
|
"$2" $3 >/dev/null &
|
||||||
@ -188,18 +188,14 @@ stop_daemon()
|
|||||||
# $2 - daemon
|
# $2 - daemon
|
||||||
# use $PIDDIR/$DAEMONBASE$1.pid as pidfile
|
# use $PIDDIR/$DAEMONBASE$1.pid as pidfile
|
||||||
local DAEMONBASE="$(basename "$2")"
|
local DAEMONBASE="$(basename "$2")"
|
||||||
local PIDFILE=$PIDDIR/$DAEMONBASE$1.pid
|
local PID PIDFILE=$PIDDIR/$DAEMONBASE$1.pid
|
||||||
echo "Stopping daemon $1: $2"
|
echo "Stopping daemon $1: $2"
|
||||||
if exists start-stop-daemon ; then
|
if [ -f "$PIDFILE" ]; then
|
||||||
start-stop-daemon -K -p "$PIDFILE" -x "$2"
|
read PID <"$PIDFILE"
|
||||||
|
kill $PID
|
||||||
|
rm -f "$PIDFILE"
|
||||||
else
|
else
|
||||||
if [ -f "$PIDFILE" ]; then
|
echo no pidfile : $PIDFILE
|
||||||
read PID <"$PIDFILE"
|
|
||||||
kill $PID
|
|
||||||
rm -f "$PIDFILE"
|
|
||||||
else
|
|
||||||
echo no pidfile : $PIDFILE
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
do_daemon()
|
do_daemon()
|
||||||
@ -273,45 +269,3 @@ create_ipset()
|
|||||||
echo "Creating ip list table (firewall type $FWTYPE)"
|
echo "Creating ip list table (firewall type $FWTYPE)"
|
||||||
"$IPSET_CR" "$@"
|
"$IPSET_CR" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
standard_mode_daemons()
|
|
||||||
{
|
|
||||||
# $1 - 1 - run, 0 - stop
|
|
||||||
|
|
||||||
local opt
|
|
||||||
|
|
||||||
[ "$TPWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$TPWS_OPT" && {
|
|
||||||
opt="--port=$TPPORT $TPWS_OPT"
|
|
||||||
filter_apply_hostlist_target opt
|
|
||||||
do_tpws $1 1 "$opt"
|
|
||||||
}
|
|
||||||
[ "$TPWS_SOCKS_ENABLE" = 1 ] && {
|
|
||||||
opt="--port=$TPPORT_SOCKS $TPWS_SOCKS_OPT"
|
|
||||||
filter_apply_hostlist_target opt
|
|
||||||
do_tpws_socks $1 2 "$opt"
|
|
||||||
}
|
|
||||||
[ "$NFQWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$NFQWS_OPT" && {
|
|
||||||
opt="--qnum=$QNUM $NFQWS_OPT"
|
|
||||||
filter_apply_hostlist_target opt
|
|
||||||
do_nfqws $1 3 "$opt"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
zapret_do_daemons()
|
|
||||||
{
|
|
||||||
# $1 - 1 - run, 0 - stop
|
|
||||||
|
|
||||||
standard_mode_daemons $1
|
|
||||||
custom_runner zapret_custom_daemons $1
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
zapret_run_daemons()
|
|
||||||
{
|
|
||||||
zapret_do_daemons 1 "$@"
|
|
||||||
}
|
|
||||||
zapret_stop_daemons()
|
|
||||||
{
|
|
||||||
zapret_do_daemons 0 "$@"
|
|
||||||
}
|
|
||||||
|
@ -74,8 +74,7 @@ case "$1" in
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
N=/etc/init.d/$NAME
|
echo "Usage: $SCRIPT {start|stop|restart|start-fw|stop-fw|restart-fw|start-daemons|stop-daemons|restart-daemons|reload-ifsets|list-ifsets|list-table}" >&2
|
||||||
echo "Usage: $N {start|stop|restart|start-fw|stop-fw|restart-fw|start-daemons|stop-daemons|restart-daemons|reload-ifsets|list-ifsets|list-table}" >&2
|
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
@ -56,7 +56,7 @@ UNAME=$(uname)
|
|||||||
unset PKTWS
|
unset PKTWS
|
||||||
case $UNAME in
|
case $UNAME in
|
||||||
Linux)
|
Linux)
|
||||||
ARCHLIST="my x86_64 x86 aarch64 arm mips64r2-msb mips32r1-lsb mips32r1-msb ppc"
|
ARCHLIST="my x86_64 x86 aarch64 arm mips64r2-msb mips32r1-lsb mips32r1-msb lexra ppc"
|
||||||
PKTWS=nfqws
|
PKTWS=nfqws
|
||||||
;;
|
;;
|
||||||
Darwin)
|
Darwin)
|
||||||
@ -68,7 +68,7 @@ case $UNAME in
|
|||||||
;;
|
;;
|
||||||
CYGWIN*)
|
CYGWIN*)
|
||||||
UNAME=CYGWIN
|
UNAME=CYGWIN
|
||||||
ARCHLIST="win64"
|
ARCHLIST="win64 win32"
|
||||||
PKTWS=winws
|
PKTWS=winws
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
@ -26,6 +26,7 @@ IPSET_DIR="$ZAPRET_BASE/ipset"
|
|||||||
. "$ZAPRET_BASE/common/ipt.sh"
|
. "$ZAPRET_BASE/common/ipt.sh"
|
||||||
. "$ZAPRET_BASE/common/installer.sh"
|
. "$ZAPRET_BASE/common/installer.sh"
|
||||||
. "$ZAPRET_BASE/common/virt.sh"
|
. "$ZAPRET_BASE/common/virt.sh"
|
||||||
|
. "$ZAPRET_BASE/common/list.sh"
|
||||||
|
|
||||||
GET_LIST="$IPSET_DIR/get_config.sh"
|
GET_LIST="$IPSET_DIR/get_config.sh"
|
||||||
|
|
||||||
@ -68,8 +69,15 @@ check_bins()
|
|||||||
echo found architecture "\"$arch\""
|
echo found architecture "\"$arch\""
|
||||||
elif [ -f "$EXEDIR/Makefile" ] && exists make; then
|
elif [ -f "$EXEDIR/Makefile" ] && exists make; then
|
||||||
echo trying to compile
|
echo trying to compile
|
||||||
[ "$SYSTEM" = "macos" ] && make_target=mac
|
case $SYSTEM in
|
||||||
make -C "$EXEDIR" $make_target || {
|
macos)
|
||||||
|
make_target=mac
|
||||||
|
;;
|
||||||
|
systemd)
|
||||||
|
make_target=systemd
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
CFLAGS="-march=native ${CFLAGS}" make -C "$EXEDIR" $make_target || {
|
||||||
echo could not compile
|
echo could not compile
|
||||||
make -C "$EXEDIR" clean
|
make -C "$EXEDIR" clean
|
||||||
exitp 8
|
exitp 8
|
||||||
@ -115,6 +123,30 @@ ws_opt_validate()
|
|||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
tpws_opt_validate()
|
||||||
|
{
|
||||||
|
ws_opt_validate "$1" || return 1
|
||||||
|
dry_run_tpws || {
|
||||||
|
echo invalid tpws options
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tpws_socks_opt_validate()
|
||||||
|
{
|
||||||
|
# --ipset allowed here
|
||||||
|
dry_run_tpws_socks || {
|
||||||
|
echo invalid tpws options
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nfqws_opt_validate()
|
||||||
|
{
|
||||||
|
ws_opt_validate "$1" || return 1
|
||||||
|
dry_run_nfqws || {
|
||||||
|
echo invalid nfqws options
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
select_mode_group()
|
select_mode_group()
|
||||||
{
|
{
|
||||||
@ -162,18 +194,17 @@ select_mode_group()
|
|||||||
select_mode_tpws_socks()
|
select_mode_tpws_socks()
|
||||||
{
|
{
|
||||||
local EDITVAR_NEWLINE_DELIMETER="--new" EDITVAR_NEWLINE_VARS="TPWS_SOCKS_OPT"
|
local EDITVAR_NEWLINE_DELIMETER="--new" EDITVAR_NEWLINE_VARS="TPWS_SOCKS_OPT"
|
||||||
# --ipset allowed here
|
select_mode_group TPWS_SOCKS_ENABLE "enable tpws socks mode on port $TPPORT_SOCKS ?" "TPPORT_SOCKS TPWS_SOCKS_OPT" tpws_socks_opt_validate TPWS_SOCKS_OPT
|
||||||
select_mode_group TPWS_SOCKS_ENABLE "enable tpws socks mode on port $TPPORT_SOCKS ?" "TPPORT_SOCKS TPWS_SOCKS_OPT"
|
|
||||||
}
|
}
|
||||||
select_mode_tpws()
|
select_mode_tpws()
|
||||||
{
|
{
|
||||||
local EDITVAR_NEWLINE_DELIMETER="--new" EDITVAR_NEWLINE_VARS="TPWS_OPT"
|
local EDITVAR_NEWLINE_DELIMETER="--new" EDITVAR_NEWLINE_VARS="TPWS_OPT"
|
||||||
select_mode_group TPWS_ENABLE "enable tpws transparent mode ?" "TPWS_PORTS TPWS_OPT" ws_opt_validate TPWS_OPT
|
select_mode_group TPWS_ENABLE "enable tpws transparent mode ?" "TPWS_PORTS TPWS_OPT" tpws_opt_validate TPWS_OPT
|
||||||
}
|
}
|
||||||
select_mode_nfqws()
|
select_mode_nfqws()
|
||||||
{
|
{
|
||||||
local EDITVAR_NEWLINE_DELIMETER="--new" EDITVAR_NEWLINE_VARS="NFQWS_OPT"
|
local EDITVAR_NEWLINE_DELIMETER="--new" EDITVAR_NEWLINE_VARS="NFQWS_OPT"
|
||||||
select_mode_group NFQWS_ENABLE "enable nfqws ?" "NFQWS_PORTS_TCP NFQWS_PORTS_UDP NFQWS_TCP_PKT_OUT NFQWS_TCP_PKT_IN NFQWS_UDP_PKT_OUT NFQWS_UDP_PKT_IN NFQWS_PORTS_TCP_KEEPALIVE NFQWS_PORTS_UDP_KEEPALIVE NFQWS_OPT" ws_opt_validate NFQWS_OPT
|
select_mode_group NFQWS_ENABLE "enable nfqws ?" "NFQWS_PORTS_TCP NFQWS_PORTS_UDP NFQWS_TCP_PKT_OUT NFQWS_TCP_PKT_IN NFQWS_UDP_PKT_OUT NFQWS_UDP_PKT_IN NFQWS_PORTS_TCP_KEEPALIVE NFQWS_PORTS_UDP_KEEPALIVE NFQWS_OPT" nfqws_opt_validate NFQWS_OPT
|
||||||
}
|
}
|
||||||
|
|
||||||
select_mode_mode()
|
select_mode_mode()
|
||||||
@ -268,7 +299,7 @@ ask_config_tmpdir()
|
|||||||
echo default tmpfs has size of 50% RAM
|
echo default tmpfs has size of 50% RAM
|
||||||
echo "RAM : $(get_ram_mb) Mb"
|
echo "RAM : $(get_ram_mb) Mb"
|
||||||
echo "DISK : $(get_free_space_mb) Mb"
|
echo "DISK : $(get_free_space_mb) Mb"
|
||||||
echo select temp file location
|
echo select temp file location
|
||||||
[ -z "$TMPDIR" ] && TMPDIR=/tmp
|
[ -z "$TMPDIR" ] && TMPDIR=/tmp
|
||||||
ask_list TMPDIR "/tmp $EXEDIR/tmp" && {
|
ask_list TMPDIR "/tmp $EXEDIR/tmp" && {
|
||||||
[ "$TMPDIR" = "/tmp" ] && TMPDIR=
|
[ "$TMPDIR" = "/tmp" ] && TMPDIR=
|
||||||
@ -364,13 +395,13 @@ copy_openwrt()
|
|||||||
local ARCH="$(get_bin_arch)"
|
local ARCH="$(get_bin_arch)"
|
||||||
local BINDIR="$1/binaries/$ARCH"
|
local BINDIR="$1/binaries/$ARCH"
|
||||||
local file
|
local file
|
||||||
|
|
||||||
[ -d "$2" ] || mkdir -p "$2"
|
[ -d "$2" ] || mkdir -p "$2"
|
||||||
|
|
||||||
mkdir "$2/tpws" "$2/nfq" "$2/ip2net" "$2/mdig" "$2/binaries" "$2/binaries/$ARCH" "$2/init.d" "$2/tmp" "$2/files"
|
mkdir "$2/tpws" "$2/nfq" "$2/ip2net" "$2/mdig" "$2/binaries" "$2/binaries/$ARCH" "$2/init.d" "$2/tmp" "$2/files"
|
||||||
cp -R "$1/files/fake" "$2/files"
|
cp -R "$1/files/fake" "$2/files"
|
||||||
cp -R "$1/common" "$1/ipset" "$2"
|
cp -R "$1/common" "$1/ipset" "$2"
|
||||||
cp -R "$1/init.d/openwrt" "$2/init.d"
|
cp -R "$1/init.d/openwrt" "$1/init.d/custom.d.examples.linux" "$2/init.d"
|
||||||
cp "$1/config" "$1/config.default" "$1/install_easy.sh" "$1/uninstall_easy.sh" "$1/install_bin.sh" "$1/install_prereq.sh" "$1/blockcheck.sh" "$2"
|
cp "$1/config" "$1/config.default" "$1/install_easy.sh" "$1/uninstall_easy.sh" "$1/install_bin.sh" "$1/install_prereq.sh" "$1/blockcheck.sh" "$2"
|
||||||
cp "$BINDIR/tpws" "$BINDIR/nfqws" "$BINDIR/ip2net" "$BINDIR/mdig" "$2/binaries/$ARCH"
|
cp "$BINDIR/tpws" "$BINDIR/nfqws" "$BINDIR/ip2net" "$BINDIR/mdig" "$2/binaries/$ARCH"
|
||||||
}
|
}
|
||||||
@ -458,7 +489,7 @@ _restore_settings()
|
|||||||
[ -z "$f" -o "$f" = "/" ] && continue
|
[ -z "$f" -o "$f" = "/" ] && continue
|
||||||
|
|
||||||
[ -f "/tmp/zapret-bkp-$i" ] && {
|
[ -f "/tmp/zapret-bkp-$i" ] && {
|
||||||
mv -f "/tmp/zapret-bkp-$i" "$ZAPRET_TARGET/$f" || rm -f "/tmp/zapret-bkp-$i"
|
mv -f "/tmp/zapret-bkp-$i" "$ZAPRET_TARGET/$f" || rm -f "/tmp/zapret-bkp-$i"
|
||||||
}
|
}
|
||||||
[ -d "/tmp/zapret-bkp-$i" ] && {
|
[ -d "/tmp/zapret-bkp-$i" ] && {
|
||||||
[ -d "$ZAPRET_TARGET/$f" ] && rm -r "$ZAPRET_TARGET/$f"
|
[ -d "$ZAPRET_TARGET/$f" ] && rm -r "$ZAPRET_TARGET/$f"
|
||||||
@ -700,7 +731,7 @@ install_linux()
|
|||||||
crontab_del_quiet
|
crontab_del_quiet
|
||||||
# desktop system. more likely up at daytime
|
# desktop system. more likely up at daytime
|
||||||
crontab_add 10 22
|
crontab_add 10 22
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo '!!! WARNING. YOUR SETUP IS INCOMPLETE !!!'
|
echo '!!! WARNING. YOUR SETUP IS INCOMPLETE !!!'
|
||||||
echo you must manually add to auto start : $INIT_SCRIPT_SRC start
|
echo you must manually add to auto start : $INIT_SCRIPT_SRC start
|
||||||
@ -748,7 +779,6 @@ deoffload_openwrt_firewall()
|
|||||||
else
|
else
|
||||||
echo system wide software flow offloading disabled. ok
|
echo system wide software flow offloading disabled. ok
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
CFLAGS += -std=gnu99 -Os
|
CFLAGS += -std=gnu99 -Os -flto=auto
|
||||||
CFLAGS_BSD = -Wno-address-of-packed-member
|
CFLAGS_BSD = -Wno-address-of-packed-member
|
||||||
CFLAGS_WIN = -static
|
CFLAGS_WIN = -static
|
||||||
LIBS =
|
LIBS =
|
||||||
@ -9,22 +9,24 @@ SRC_FILES = ip2net.c qsort.c
|
|||||||
all: ip2net
|
all: ip2net
|
||||||
|
|
||||||
ip2net: $(SRC_FILES)
|
ip2net: $(SRC_FILES)
|
||||||
$(CC) -s $(CFLAGS) -o ip2net $(SRC_FILES) $(LDFLAGS) $(LIBS)
|
$(CC) -s $(CFLAGS) -o ip2net $(SRC_FILES) $(LIBS) $(LDFLAGS)
|
||||||
|
|
||||||
|
systemd: ip2net
|
||||||
|
|
||||||
android: ip2net
|
android: ip2net
|
||||||
|
|
||||||
bsd: $(SRC_FILES)
|
bsd: $(SRC_FILES)
|
||||||
$(CC) -s $(CFLAGS) $(CFLAGS_BSD) -o ip2net $(SRC_FILES) $(LDFLAGS) $(LIBS)
|
$(CC) -s $(CFLAGS) $(CFLAGS_BSD) -o ip2net $(SRC_FILES) $(LIBS) $(LDFLAGS)
|
||||||
|
|
||||||
mac: $(SRC_FILES)
|
mac: $(SRC_FILES)
|
||||||
$(CC) $(CFLAGS) $(CFLAGS_BSD) -o ip2neta $(SRC_FILES) $(LDFLAGS) -target arm64-apple-macos10.8 $(LIBS)
|
$(CC) $(CFLAGS) $(CFLAGS_BSD) -o ip2neta $(SRC_FILES) -target arm64-apple-macos10.8 $(LIBS) $(LDFLAGS)
|
||||||
$(CC) $(CFLAGS) $(CFLAGS_BSD) -o ip2netx $(SRC_FILES) $(LDFLAGS) -target x86_64-apple-macos10.8 $(LIBS)
|
$(CC) $(CFLAGS) $(CFLAGS_BSD) -o ip2netx $(SRC_FILES) -target x86_64-apple-macos10.8 $(LIBS) $(LDFLAGS)
|
||||||
strip ip2neta ip2netx
|
strip ip2neta ip2netx
|
||||||
lipo -create -output ip2net ip2netx ip2neta
|
lipo -create -output ip2net ip2netx ip2neta
|
||||||
rm -f ip2netx ip2neta
|
rm -f ip2netx ip2neta
|
||||||
|
|
||||||
win: $(SRC_FILES)
|
win: $(SRC_FILES)
|
||||||
$(CC) -s $(CFLAGS) $(CFLAGS_WIN) -o ip2net $(SRC_FILES) $(LDFLAGS) $(LIBS_WIN)
|
$(CC) -s $(CFLAGS) $(CFLAGS_WIN) -o ip2net $(SRC_FILES) $(LIBS_WIN) $(LDFLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f ip2net *.o
|
rm -f ip2net *.o
|
||||||
|
@ -192,7 +192,7 @@ static void ip6_and(const struct in6_addr * restrict a, const struct in6_addr *
|
|||||||
static void rtrim(char *s)
|
static void rtrim(char *s)
|
||||||
{
|
{
|
||||||
if (s)
|
if (s)
|
||||||
for (char *p = s + strlen(s) - 1; p >= s && (*p == '\n' || *p == '\r'); p--) *p = '\0';
|
for (char *p = s + strlen(s) - 1; p >= s && (*p == '\n' || *p == '\r' || *p == ' ' || *p == '\t'); p--) *p = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -217,6 +217,36 @@ static void exithelp(void)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define STRINGIFY(x) #x
|
||||||
|
#define TOSTRING(x) STRINGIFY(x)
|
||||||
|
#if defined(ZAPRET_GH_VER) || defined (ZAPRET_GH_HASH)
|
||||||
|
#define PRINT_VER printf("github version %s (%s)\n\n", TOSTRING(ZAPRET_GH_VER), TOSTRING(ZAPRET_GH_HASH))
|
||||||
|
#else
|
||||||
|
#define PRINT_VER printf("self-built version %s %s\n\n", __DATE__, __TIME__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum opt_indices {
|
||||||
|
IDX_HELP,
|
||||||
|
IDX_H,
|
||||||
|
IDX_4,
|
||||||
|
IDX_6,
|
||||||
|
IDX_PREFIX_LENGTH,
|
||||||
|
IDX_V4_THRESHOLD,
|
||||||
|
IDX_V6_THRESHOLD,
|
||||||
|
IDX_LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct option long_options[] = {
|
||||||
|
[IDX_HELP] = {"help", no_argument, 0, 0},
|
||||||
|
[IDX_H] = {"h", no_argument, 0, 0},
|
||||||
|
[IDX_4] = {"4", no_argument, 0, 0},
|
||||||
|
[IDX_6] = {"6", no_argument, 0, 0},
|
||||||
|
[IDX_PREFIX_LENGTH] = {"prefix-length", required_argument, 0, 0},
|
||||||
|
[IDX_V4_THRESHOLD] = {"v4-threshold", required_argument, 0, 0},
|
||||||
|
[IDX_V6_THRESHOLD] = {"v6-threshold", required_argument, 0, 0},
|
||||||
|
[IDX_LAST] = {NULL, 0, NULL, 0},
|
||||||
|
};
|
||||||
|
|
||||||
static void parse_params(int argc, char *argv[])
|
static void parse_params(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
@ -228,32 +258,23 @@ static void parse_params(int argc, char *argv[])
|
|||||||
params.pctdiv = DEFAULT_PCTDIV;
|
params.pctdiv = DEFAULT_PCTDIV;
|
||||||
params.v6_threshold = DEFAULT_V6_THRESHOLD;
|
params.v6_threshold = DEFAULT_V6_THRESHOLD;
|
||||||
|
|
||||||
const struct option long_options[] = {
|
|
||||||
{ "help",no_argument,0,0 },// optidx=0
|
|
||||||
{ "h",no_argument,0,0 },// optidx=1
|
|
||||||
{ "4",no_argument,0,0 },// optidx=2
|
|
||||||
{ "6",no_argument,0,0 },// optidx=3
|
|
||||||
{ "prefix-length",required_argument,0,0 },// optidx=4
|
|
||||||
{ "v4-threshold",required_argument,0,0 },// optidx=5
|
|
||||||
{ "v6-threshold",required_argument,0,0 },// optidx=6
|
|
||||||
{ NULL,0,NULL,0 }
|
|
||||||
};
|
|
||||||
while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1)
|
while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1)
|
||||||
{
|
{
|
||||||
if (v) exithelp();
|
if (v) exithelp();
|
||||||
switch (option_index)
|
switch (option_index)
|
||||||
{
|
{
|
||||||
case 0:
|
case IDX_HELP:
|
||||||
case 1:
|
case IDX_H:
|
||||||
|
PRINT_VER;
|
||||||
exithelp();
|
exithelp();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case IDX_4:
|
||||||
params.ipv6 = false;
|
params.ipv6 = false;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case IDX_6:
|
||||||
params.ipv6 = true;
|
params.ipv6 = true;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case IDX_PREFIX_LENGTH:
|
||||||
i = sscanf(optarg,"%u-%u",&plen1,&plen2);
|
i = sscanf(optarg,"%u-%u",&plen1,&plen2);
|
||||||
if (i == 1) plen2 = plen1;
|
if (i == 1) plen2 = plen1;
|
||||||
if (i<=0 || plen2<plen1 || !plen1 || !plen2)
|
if (i<=0 || plen2<plen1 || !plen1 || !plen2)
|
||||||
@ -262,7 +283,7 @@ static void parse_params(int argc, char *argv[])
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case IDX_V4_THRESHOLD:
|
||||||
i = sscanf(optarg, "%u/%u", ¶ms.pctmult, ¶ms.pctdiv);
|
i = sscanf(optarg, "%u/%u", ¶ms.pctmult, ¶ms.pctdiv);
|
||||||
if (i!=2 || params.pctdiv<2 || params.pctmult<1 || params.pctmult>=params.pctdiv)
|
if (i!=2 || params.pctdiv<2 || params.pctmult<1 || params.pctmult>=params.pctdiv)
|
||||||
{
|
{
|
||||||
@ -270,7 +291,7 @@ static void parse_params(int argc, char *argv[])
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case IDX_V6_THRESHOLD:
|
||||||
i = sscanf(optarg, "%u", ¶ms.v6_threshold);
|
i = sscanf(optarg, "%u", ¶ms.v6_threshold);
|
||||||
if (i != 1 || params.v6_threshold<1)
|
if (i != 1 || params.v6_threshold<1)
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@ get_antifilter()
|
|||||||
[ "$DISABLE_IPV4" != "1" ] && {
|
[ "$DISABLE_IPV4" != "1" ] && {
|
||||||
curl --fail --max-time 150 --connect-timeout 20 --max-filesize 41943040 -k -L "$1" | cut_local >"$ZIPLISTTMP" &&
|
curl --fail --max-time 150 --connect-timeout 20 --max-filesize 41943040 -k -L "$1" | cut_local >"$ZIPLISTTMP" &&
|
||||||
{
|
{
|
||||||
dlsize=$(LANG=C wc -c "$ZIPLISTTMP" | xargs | cut -f 1 -d ' ')
|
dlsize=$(LC_ALL=C LANG=C wc -c "$ZIPLISTTMP" | xargs | cut -f 1 -d ' ')
|
||||||
if [ $dlsize -lt 102400 ]; then
|
if [ $dlsize -lt 102400 ]; then
|
||||||
echo list file is too small. can be bad.
|
echo list file is too small. can be bad.
|
||||||
exit 2
|
exit 2
|
||||||
|
28
ipset/def.sh
28
ipset/def.sh
@ -5,7 +5,7 @@ ZAPRET_RW=${ZAPRET_RW:-"$ZAPRET_BASE"}
|
|||||||
ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
|
ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
|
||||||
IPSET_RW_DIR="$ZAPRET_RW/ipset"
|
IPSET_RW_DIR="$ZAPRET_RW/ipset"
|
||||||
|
|
||||||
. "$ZAPRET_CONFIG"
|
[ -f "$ZAPRET_CONFIG" ] && . "$ZAPRET_CONFIG"
|
||||||
. "$ZAPRET_BASE/common/base.sh"
|
. "$ZAPRET_BASE/common/base.sh"
|
||||||
|
|
||||||
[ -z "$TMPDIR" ] && TMPDIR=/tmp
|
[ -z "$TMPDIR" ] && TMPDIR=/tmp
|
||||||
@ -141,6 +141,18 @@ zzsize()
|
|||||||
printf 0
|
printf 0
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
zzcopy()
|
||||||
|
{
|
||||||
|
local is_gz=0
|
||||||
|
zztest "$1" && is_gz=1
|
||||||
|
if [ "$GZIP_LISTS" = 1 -a $is_gz = 1 ]; then
|
||||||
|
cp "$1" "${2}.gz"
|
||||||
|
elif [ "$GZIP_LISTS" != 1 -a $is_gz != 1 ]; then
|
||||||
|
cp "$1" "$2"
|
||||||
|
else
|
||||||
|
zzcat "$1" | zz "$2"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
digger()
|
digger()
|
||||||
{
|
{
|
||||||
@ -255,3 +267,17 @@ getipban()
|
|||||||
_get_ipban
|
_get_ipban
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hup_zapret_daemons()
|
||||||
|
{
|
||||||
|
echo forcing zapret daemons to reload their hostlist
|
||||||
|
if exists killall; then
|
||||||
|
killall -HUP tpws nfqws dvtws 2>/dev/null
|
||||||
|
elif exists pkill; then
|
||||||
|
pkill -HUP ^tpws$
|
||||||
|
pkill -HUP ^nfqws$
|
||||||
|
pkill -HUP ^dvtws$
|
||||||
|
else
|
||||||
|
echo no mass killer available ! cant HUP zapret daemons
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
@ -21,7 +21,7 @@ curl -H "Accept-Encoding: gzip" -k --fail --max-time 600 --connect-timeout 5 --r
|
|||||||
exit 2
|
exit 2
|
||||||
}
|
}
|
||||||
|
|
||||||
dlsize=$(LANG=C wc -c "$ZDOM" | xargs | cut -f 1 -d ' ')
|
dlsize=$(LC_ALL=C LANG=C wc -c "$ZDOM" | xargs | cut -f 1 -d ' ')
|
||||||
if test $dlsize -lt 102400; then
|
if test $dlsize -lt 102400; then
|
||||||
echo list file is too small. can be bad.
|
echo list file is too small. can be bad.
|
||||||
exit 2
|
exit 2
|
||||||
@ -31,4 +31,6 @@ sort -u "$ZDOM" | zz "$ZHOSTLIST"
|
|||||||
|
|
||||||
rm -f "$ZDOM"
|
rm -f "$ZDOM"
|
||||||
|
|
||||||
|
hup_zapret_daemons
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
IPSET_DIR="$(dirname "$0")"
|
IPSET_DIR="$(dirname "$0")"
|
||||||
IPSET_DIR="$(cd "$IPSET_DIR"; pwd)"
|
IPSET_DIR="$(cd "$IPSET_DIR"; pwd)"
|
||||||
|
|
||||||
. "$IPSET_DIR/../config"
|
[ -f "$IPSET_DIR/../config" ] && . "$IPSET_DIR/../config"
|
||||||
|
|
||||||
[ -z "$GETLIST" ] && GETLIST=get_ipban.sh
|
[ -z "$GETLIST" ] && GETLIST=get_ipban.sh
|
||||||
[ -x "$IPSET_DIR/$GETLIST" ] && exec "$IPSET_DIR/$GETLIST"
|
[ -x "$IPSET_DIR/$GETLIST" ] && exec "$IPSET_DIR/$GETLIST"
|
||||||
|
@ -5,9 +5,9 @@ IPSET_DIR="$(cd "$IPSET_DIR"; pwd)"
|
|||||||
|
|
||||||
. "$IPSET_DIR/def.sh"
|
. "$IPSET_DIR/def.sh"
|
||||||
|
|
||||||
ZREESTR="$TMPDIR/zapret.txt"
|
ZREESTR="$TMPDIR/zapret.txt.gz"
|
||||||
IPB="$TMPDIR/ipb.txt"
|
IPB="$TMPDIR/ipb.txt"
|
||||||
ZURL_REESTR=https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv
|
ZURL_REESTR=https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv.gz
|
||||||
|
|
||||||
dl_checked()
|
dl_checked()
|
||||||
{
|
{
|
||||||
@ -21,7 +21,7 @@ dl_checked()
|
|||||||
echo list download failed : $1
|
echo list download failed : $1
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
dlsize=$(LANG=C wc -c "$2" | xargs | cut -f 1 -d ' ')
|
dlsize=$(LC_ALL=C LANG=C wc -c "$2" | xargs | cut -f 1 -d ' ')
|
||||||
if test $dlsize -lt $3; then
|
if test $dlsize -lt $3; then
|
||||||
echo list is too small : $dlsize bytes. can be bad.
|
echo list is too small : $dlsize bytes. can be bad.
|
||||||
return 2
|
return 2
|
||||||
@ -31,11 +31,11 @@ dl_checked()
|
|||||||
|
|
||||||
reestr_list()
|
reestr_list()
|
||||||
{
|
{
|
||||||
LANG=C cut -s -f2 -d';' "$ZREESTR" | LANG=C nice -n 5 sed -Ee 's/^\*\.(.+)$/\1/' -ne 's/^[a-z0-9A-Z._-]+$/&/p' | $AWK '{ print tolower($0) }'
|
LC_ALL=C LANG=C gunzip -c "$ZREESTR" | cut -s -f2 -d';' | LC_ALL=C LANG=C nice -n 5 sed -Ee 's/^\*\.(.+)$/\1/' -ne 's/^[a-z0-9A-Z._-]+$/&/p' | $AWK '{ print tolower($0) }'
|
||||||
}
|
}
|
||||||
reestr_extract_ip()
|
reestr_extract_ip()
|
||||||
{
|
{
|
||||||
LANG=C nice -n 5 $AWK -F ';' '($1 ~ /^([0-9]{1,3}\.){3}[0-9]{1,3}/) && (($2 == "" && $3 == "") || ($1 == $2)) {gsub(/ \| /, RS); print $1}' "$ZREESTR" | LANG=C $AWK '{split($1, a, /\|/); for (i in a) {print a[i]}}'
|
LC_ALL=C LANG=C gunzip -c | nice -n 5 $AWK -F ';' '($1 ~ /^([0-9]{1,3}\.){3}[0-9]{1,3}/) && (($2 == "" && $3 == "") || ($1 == $2)) {gsub(/ \| /, RS); print $1}' | LC_ALL=C LANG=C $AWK '{split($1, a, /\|/); for (i in a) {print a[i]}}'
|
||||||
}
|
}
|
||||||
|
|
||||||
ipban_fin()
|
ipban_fin()
|
||||||
@ -58,6 +58,8 @@ rm -f "$ZREESTR"
|
|||||||
[ "$DISABLE_IPV6" != "1" ] && $AWK '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}($|(\/[0-9]{2,3}$))/' "$IPB" | cut_local6 | ip2net6 | zz "$ZIPLIST_IPBAN6"
|
[ "$DISABLE_IPV6" != "1" ] && $AWK '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}($|(\/[0-9]{2,3}$))/' "$IPB" | cut_local6 | ip2net6 | zz "$ZIPLIST_IPBAN6"
|
||||||
rm -f "$IPB"
|
rm -f "$IPB"
|
||||||
|
|
||||||
|
hup_zapret_daemons
|
||||||
|
|
||||||
ipban_fin
|
ipban_fin
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -24,12 +24,12 @@ dl()
|
|||||||
echo list download failed : $1
|
echo list download failed : $1
|
||||||
exit 2
|
exit 2
|
||||||
}
|
}
|
||||||
dlsize=$(LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ')
|
dlsize=$(LC_ALL=C LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ')
|
||||||
if test $dlsize -lt $3; then
|
if test $dlsize -lt $3; then
|
||||||
echo list is too small : $dlsize bytes. can be bad.
|
echo list is too small : $dlsize bytes. can be bad.
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
zzcat "$TMPLIST" | zz "$2"
|
zzcopy "$TMPLIST" "$2"
|
||||||
rm -f "$TMPLIST"
|
rm -f "$TMPLIST"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,12 +24,12 @@ dl()
|
|||||||
echo list download failed : $1
|
echo list download failed : $1
|
||||||
exit 2
|
exit 2
|
||||||
}
|
}
|
||||||
dlsize=$(LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ')
|
dlsize=$(LC_ALL=C LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ')
|
||||||
if test $dlsize -lt $3; then
|
if test $dlsize -lt $3; then
|
||||||
echo list is too small : $dlsize bytes. can be bad.
|
echo list is too small : $dlsize bytes. can be bad.
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
zzcat "$TMPLIST" | zz "$2"
|
zzcopy "$TMPLIST" "$2"
|
||||||
rm -f "$TMPLIST"
|
rm -f "$TMPLIST"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,17 +23,19 @@ dl()
|
|||||||
echo list download failed : $1
|
echo list download failed : $1
|
||||||
exit 2
|
exit 2
|
||||||
}
|
}
|
||||||
dlsize=$(LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ')
|
dlsize=$(LC_ALL=C LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ')
|
||||||
if test $dlsize -lt $3; then
|
if test $dlsize -lt $3; then
|
||||||
echo list is too small : $dlsize bytes. can be bad.
|
echo list is too small : $dlsize bytes. can be bad.
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
zzcat "$TMPLIST" | zz "$2"
|
zzcopy "$TMPLIST" "$2"
|
||||||
rm -f "$TMPLIST"
|
rm -f "$TMPLIST"
|
||||||
}
|
}
|
||||||
|
|
||||||
dl "$URL" "$ZHOSTLIST" 65536 67108864
|
dl "$URL" "$ZHOSTLIST" 65536 67108864
|
||||||
|
|
||||||
|
hup_zapret_daemons
|
||||||
|
|
||||||
[ "$DISABLE_IPV4" != "1" ] && dl "$IPB4" "$ZIPLIST_IPBAN" 8192 1048576
|
[ "$DISABLE_IPV4" != "1" ] && dl "$IPB4" "$ZIPLIST_IPBAN" 8192 1048576
|
||||||
[ "$DISABLE_IPV6" != "1" ] && dl "$IPB6" "$ZIPLIST_IPBAN6" 128 1048576
|
[ "$DISABLE_IPV6" != "1" ] && dl "$IPB6" "$ZIPLIST_IPBAN6" 128 1048576
|
||||||
|
|
||||||
|
@ -5,12 +5,12 @@ IPSET_DIR="$(cd "$IPSET_DIR"; pwd)"
|
|||||||
|
|
||||||
. "$IPSET_DIR/def.sh"
|
. "$IPSET_DIR/def.sh"
|
||||||
|
|
||||||
ZREESTR="$TMPDIR/zapret.txt"
|
ZREESTR="$TMPDIR/zapret.txt.gz"
|
||||||
ZDIG="$TMPDIR/zapret-dig.txt"
|
ZDIG="$TMPDIR/zapret-dig.txt"
|
||||||
IPB="$TMPDIR/ipb.txt"
|
IPB="$TMPDIR/ipb.txt"
|
||||||
ZIPLISTTMP="$TMPDIR/zapret-ip.txt"
|
ZIPLISTTMP="$TMPDIR/zapret-ip.txt"
|
||||||
#ZURL=https://reestr.rublacklist.net/api/current
|
#ZURL=https://reestr.rublacklist.net/api/current
|
||||||
ZURL_REESTR=https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv
|
ZURL_REESTR=https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv.gz
|
||||||
|
|
||||||
dl_checked()
|
dl_checked()
|
||||||
{
|
{
|
||||||
@ -24,7 +24,7 @@ dl_checked()
|
|||||||
echo list download failed : $1
|
echo list download failed : $1
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
dlsize=$(LANG=C wc -c "$2" | xargs | cut -f 1 -d ' ')
|
dlsize=$(LC_ALL=C LANG=C wc -c "$2" | xargs | cut -f 1 -d ' ')
|
||||||
if test $dlsize -lt $3; then
|
if test $dlsize -lt $3; then
|
||||||
echo list is too small : $dlsize bytes. can be bad.
|
echo list is too small : $dlsize bytes. can be bad.
|
||||||
return 2
|
return 2
|
||||||
@ -34,11 +34,11 @@ dl_checked()
|
|||||||
|
|
||||||
reestr_list()
|
reestr_list()
|
||||||
{
|
{
|
||||||
LANG=C cut -s -f2 -d';' "$ZREESTR" | LANG=C nice -n 5 sed -Ee 's/^\*\.(.+)$/\1/' -ne 's/^[a-z0-9A-Z._-]+$/&/p'
|
LC_ALL=C LANG=C gunzip -c "$ZREESTR" | cut -s -f2 -d';' | LC_ALL=C LANG=C nice -n 5 sed -Ee 's/^\*\.(.+)$/\1/' -ne 's/^[a-z0-9A-Z._-]+$/&/p' | $AWK '{ print tolower($0) }'
|
||||||
}
|
}
|
||||||
reestr_extract_ip()
|
reestr_extract_ip()
|
||||||
{
|
{
|
||||||
LANG=C nice -n 5 $AWK -F ';' '($1 ~ /^([0-9]{1,3}\.){3}[0-9]{1,3}/) && (($2 == "" && $3 == "") || ($1 == $2)) {gsub(/ \| /, RS); print $1}' "$ZREESTR" | LANG=C $AWK '{split($1, a, /\|/); for (i in a) {print a[i]}}'
|
LC_ALL=C LANG=C gunzip -c | nice -n 5 $AWK -F ';' '($1 ~ /^([0-9]{1,3}\.){3}[0-9]{1,3}/) && (($2 == "" && $3 == "") || ($1 == $2)) {gsub(/ \| /, RS); print $1}' | LC_ALL=C LANG=C $AWK '{split($1, a, /\|/); for (i in a) {print a[i]}}'
|
||||||
}
|
}
|
||||||
|
|
||||||
getuser && {
|
getuser && {
|
||||||
|
@ -20,12 +20,12 @@ dl()
|
|||||||
echo list download failed : $1
|
echo list download failed : $1
|
||||||
exit 2
|
exit 2
|
||||||
}
|
}
|
||||||
dlsize=$(LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ')
|
dlsize=$(LC_ALL=C LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ')
|
||||||
if test $dlsize -lt $3; then
|
if test $dlsize -lt $3; then
|
||||||
echo list is too small : $dlsize bytes. can be bad.
|
echo list is too small : $dlsize bytes. can be bad.
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
zzcat "$TMPLIST" | tr -d '\015' | zz "$2"
|
zzcopy "$TMPLIST" "$2"
|
||||||
rm -f "$TMPLIST"
|
rm -f "$TMPLIST"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,4 +37,6 @@ getipban || FAIL=1
|
|||||||
|
|
||||||
dl "$URL" "$ZHOSTLIST" 32768 4194304
|
dl "$URL" "$ZHOSTLIST" 32768 4194304
|
||||||
|
|
||||||
|
hup_zapret_daemons
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -20,13 +20,12 @@ dl()
|
|||||||
echo list download failed : $1
|
echo list download failed : $1
|
||||||
exit 2
|
exit 2
|
||||||
}
|
}
|
||||||
dlsize=$(LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ')
|
dlsize=$(LC_ALL=C LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ')
|
||||||
if test $dlsize -lt $3; then
|
if test $dlsize -lt $3; then
|
||||||
echo list is too small : $dlsize bytes. can be bad.
|
echo list is too small : $dlsize bytes. can be bad.
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
# remove DOS EOL \r
|
zzcopy "$TMPLIST" "$2"
|
||||||
zzcat "$TMPLIST" | tr -d '\015' | zz "$2"
|
|
||||||
rm -f "$TMPLIST"
|
rm -f "$TMPLIST"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
127.0.0.0/8
|
||||||
10.0.0.0/8
|
10.0.0.0/8
|
||||||
172.16.0.0/12
|
172.16.0.0/12
|
||||||
192.168.0.0/16
|
192.168.0.0/16
|
||||||
169.254.0.0/16
|
169.254.0.0/16
|
||||||
|
::1
|
||||||
fc00::/7
|
fc00::/7
|
||||||
fe80::/10
|
fe80::/10
|
||||||
|
@ -10,23 +10,25 @@ SRC_FILES = *.c
|
|||||||
all: mdig
|
all: mdig
|
||||||
|
|
||||||
mdig: $(SRC_FILES)
|
mdig: $(SRC_FILES)
|
||||||
$(CC) -s $(CFLAGS) -o mdig $(SRC_FILES) $(LDFLAGS) $(LIBS)
|
$(CC) -s $(CFLAGS) -o mdig $(SRC_FILES) $(LIBS) $(LDFLAGS)
|
||||||
|
|
||||||
|
systemd: mdig
|
||||||
|
|
||||||
android: $(SRC_FILES)
|
android: $(SRC_FILES)
|
||||||
$(CC) -s $(CFLAGS) -o mdig $(SRC_FILES) $(LDFLAGS) $(LIBS_ANDROID)
|
$(CC) -s $(CFLAGS) -o mdig $(SRC_FILES) $(LIBS_ANDROID) $(LDFLAGS)
|
||||||
|
|
||||||
bsd: $(SRC_FILES)
|
bsd: $(SRC_FILES)
|
||||||
$(CC) -s $(CFLAGS) $(CFLAGS_BSD) -o mdig $(SRC_FILES) $(LDFLAGS) $(LIBS)
|
$(CC) -s $(CFLAGS) $(CFLAGS_BSD) -o mdig $(SRC_FILES) $(LIBS) $(LDFLAGS)
|
||||||
|
|
||||||
mac: $(SRC_FILES)
|
mac: $(SRC_FILES)
|
||||||
$(CC) $(CFLAGS) $(CFLAGS_BSD) -o mdiga $(SRC_FILES) $(LDFLAGS) -target arm64-apple-macos10.8 $(LIBS_BSD)
|
$(CC) $(CFLAGS) $(CFLAGS_BSD) -o mdiga $(SRC_FILES) -target arm64-apple-macos10.8 $(LIBS_BSD) $(LDFLAGS)
|
||||||
$(CC) $(CFLAGS) $(CFLAGS_BSD) -o mdigx $(SRC_FILES) $(LDFLAGS) -target x86_64-apple-macos10.8 $(LIBS_BSD)
|
$(CC) $(CFLAGS) $(CFLAGS_BSD) -o mdigx $(SRC_FILES) -target x86_64-apple-macos10.8 $(LIBS_BSD) $(LDFLAGS)
|
||||||
strip mdiga mdigx
|
strip mdiga mdigx
|
||||||
lipo -create -output mdig mdigx mdiga
|
lipo -create -output mdig mdigx mdiga
|
||||||
rm -f mdigx mdiga
|
rm -f mdigx mdiga
|
||||||
|
|
||||||
win: $(SRC_FILES)
|
win: $(SRC_FILES)
|
||||||
$(CC) -s $(CFLAGS) $(CFLAGS_WIN) -o mdig $(SRC_FILES) $(LDFLAGS) $(LIBS_WIN)
|
$(CC) -s $(CFLAGS) $(CFLAGS_WIN) -o mdig $(SRC_FILES) $(LIBS_WIN) $(LDFLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f mdig *.o
|
rm -f mdig *.o
|
||||||
|
69
mdig/mdig.c
69
mdig/mdig.c
@ -35,7 +35,7 @@
|
|||||||
static void trimstr(char *s)
|
static void trimstr(char *s)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
for (p = s + strlen(s) - 1; p >= s && (*p == '\n' || *p == '\r'); p--) *p = '\0';
|
for (p = s + strlen(s) - 1; p >= s && (*p == '\n' || *p == '\r' || *p == ' ' || *p == '\t'); p--) *p = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* eai_str(int r)
|
static const char* eai_str(int r)
|
||||||
@ -458,25 +458,47 @@ static void exithelp(void)
|
|||||||
);
|
);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define STRINGIFY(x) #x
|
||||||
|
#define TOSTRING(x) STRINGIFY(x)
|
||||||
|
#if defined(ZAPRET_GH_VER) || defined (ZAPRET_GH_HASH)
|
||||||
|
#define PRINT_VER printf("github version %s (%s)\n\n", TOSTRING(ZAPRET_GH_VER), TOSTRING(ZAPRET_GH_HASH))
|
||||||
|
#else
|
||||||
|
#define PRINT_VER printf("self-built version %s %s\n\n", __DATE__, __TIME__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum opt_indices {
|
||||||
|
IDX_HELP,
|
||||||
|
IDX_THREADS,
|
||||||
|
IDX_FAMILY,
|
||||||
|
IDX_VERBOSE,
|
||||||
|
IDX_STATS,
|
||||||
|
IDX_LOG_RESOLVED,
|
||||||
|
IDX_LOG_FAILED,
|
||||||
|
IDX_DNS_MAKE_QUERY,
|
||||||
|
IDX_DNS_PARSE_QUERY,
|
||||||
|
IDX_LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct option long_options[] = {
|
||||||
|
[IDX_HELP] = {"help", no_argument, 0, 0},
|
||||||
|
[IDX_THREADS] = {"threads", required_argument, 0, 0},
|
||||||
|
[IDX_FAMILY] = {"family", required_argument, 0, 0},
|
||||||
|
[IDX_VERBOSE] = {"verbose", no_argument, 0, 0},
|
||||||
|
[IDX_STATS] = {"stats", required_argument, 0, 0},
|
||||||
|
[IDX_LOG_RESOLVED] = {"log-resolved", required_argument, 0, 0},
|
||||||
|
[IDX_LOG_FAILED] = {"log-failed", required_argument, 0, 0},
|
||||||
|
[IDX_DNS_MAKE_QUERY] = {"dns-make-query", required_argument, 0, 0},
|
||||||
|
[IDX_DNS_PARSE_QUERY] = {"dns-parse-query", no_argument, 0, 0},
|
||||||
|
[IDX_LAST] = {NULL, 0, NULL, 0},
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int r, v, option_index = 0;
|
int r, v, option_index = 0;
|
||||||
char fn1[256],fn2[256];
|
char fn1[256],fn2[256];
|
||||||
char dom[256];
|
char dom[256];
|
||||||
|
|
||||||
static const struct option long_options[] = {
|
|
||||||
{"help",no_argument,0,0}, // optidx=0
|
|
||||||
{"threads",required_argument,0,0}, // optidx=1
|
|
||||||
{"family",required_argument,0,0}, // optidx=2
|
|
||||||
{"verbose",no_argument,0,0}, // optidx=3
|
|
||||||
{"stats",required_argument,0,0}, // optidx=4
|
|
||||||
{"log-resolved",required_argument,0,0}, // optidx=5
|
|
||||||
{"log-failed",required_argument,0,0}, // optidx=6
|
|
||||||
{"dns-make-query",required_argument,0,0}, // optidx=7
|
|
||||||
{"dns-parse-query",no_argument,0,0}, // optidx=8
|
|
||||||
{NULL,0,NULL,0}
|
|
||||||
};
|
|
||||||
|
|
||||||
memset(&glob, 0, sizeof(glob));
|
memset(&glob, 0, sizeof(glob));
|
||||||
*fn1 = *fn2 = *dom = 0;
|
*fn1 = *fn2 = *dom = 0;
|
||||||
glob.family = FAMILY4;
|
glob.family = FAMILY4;
|
||||||
@ -486,10 +508,11 @@ int main(int argc, char **argv)
|
|||||||
if (v) exithelp();
|
if (v) exithelp();
|
||||||
switch (option_index)
|
switch (option_index)
|
||||||
{
|
{
|
||||||
case 0: /* help */
|
case IDX_HELP:
|
||||||
|
PRINT_VER;
|
||||||
exithelp();
|
exithelp();
|
||||||
break;
|
break;
|
||||||
case 1: /* threads */
|
case IDX_THREADS:
|
||||||
glob.threads = optarg ? atoi(optarg) : 0;
|
glob.threads = optarg ? atoi(optarg) : 0;
|
||||||
if (glob.threads <= 0 || glob.threads > 100)
|
if (glob.threads <= 0 || glob.threads > 100)
|
||||||
{
|
{
|
||||||
@ -497,7 +520,7 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: /* family */
|
case IDX_FAMILY:
|
||||||
if (!strcmp(optarg, "4"))
|
if (!strcmp(optarg, "4"))
|
||||||
glob.family = FAMILY4;
|
glob.family = FAMILY4;
|
||||||
else if (!strcmp(optarg, "6"))
|
else if (!strcmp(optarg, "6"))
|
||||||
@ -510,25 +533,25 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3: /* verbose */
|
case IDX_VERBOSE:
|
||||||
glob.verbose = '\1';
|
glob.verbose = '\1';
|
||||||
break;
|
break;
|
||||||
case 4: /* stats */
|
case IDX_STATS:
|
||||||
glob.stats_every = optarg ? atoi(optarg) : 0;
|
glob.stats_every = optarg ? atoi(optarg) : 0;
|
||||||
break;
|
break;
|
||||||
case 5: /* log-resolved */
|
case IDX_LOG_RESOLVED:
|
||||||
strncpy(fn1,optarg,sizeof(fn1));
|
strncpy(fn1,optarg,sizeof(fn1));
|
||||||
fn1[sizeof(fn1)-1] = 0;
|
fn1[sizeof(fn1)-1] = 0;
|
||||||
break;
|
break;
|
||||||
case 6: /* log-failed */
|
case IDX_LOG_FAILED:
|
||||||
strncpy(fn2,optarg,sizeof(fn2));
|
strncpy(fn2,optarg,sizeof(fn2));
|
||||||
fn2[sizeof(fn2)-1] = 0;
|
fn2[sizeof(fn2)-1] = 0;
|
||||||
break;
|
break;
|
||||||
case 7: /* dns-make-query */
|
case IDX_DNS_MAKE_QUERY:
|
||||||
strncpy(dom,optarg,sizeof(dom));
|
strncpy(dom,optarg,sizeof(dom));
|
||||||
dom[sizeof(dom)-1] = 0;
|
dom[sizeof(dom)-1] = 0;
|
||||||
break;
|
break;
|
||||||
case 8: /* dns-parse-query */
|
case IDX_DNS_PARSE_QUERY:
|
||||||
return dns_parse_query();
|
return dns_parse_query();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
CC ?= cc
|
CC ?= cc
|
||||||
CFLAGS += -std=gnu99 -s -Os -Wno-address-of-packed-member
|
CFLAGS += -std=gnu99 -s -Os -Wno-address-of-packed-member -flto=auto
|
||||||
LIBS = -lz
|
LIBS = -lz
|
||||||
SRC_FILES = *.c crypto/*.c
|
SRC_FILES = *.c crypto/*.c
|
||||||
|
|
||||||
all: dvtws
|
all: dvtws
|
||||||
|
|
||||||
dvtws: $(SRC_FILES)
|
dvtws: $(SRC_FILES)
|
||||||
$(CC) $(CFLAGS) -o dvtws $(SRC_FILES) $(LDFLAGS) $(LIBS)
|
$(CC) $(CFLAGS) -o dvtws $(SRC_FILES) $(LIBS) $(LDFLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f dvtws
|
rm -f dvtws
|
||||||
|
20
nfq/Makefile
20
nfq/Makefile
@ -1,9 +1,10 @@
|
|||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
CFLAGS += -std=gnu99 -Os
|
CFLAGS += -std=gnu99 -Os -flto=auto
|
||||||
|
CFLAGS_SYSTEMD = -DUSE_SYSTEMD
|
||||||
CFLAGS_BSD = -Wno-address-of-packed-member
|
CFLAGS_BSD = -Wno-address-of-packed-member
|
||||||
CFLAGS_MAC = -mmacosx-version-min=10.8
|
|
||||||
CFLAGS_CYGWIN = -Wno-address-of-packed-member -static
|
CFLAGS_CYGWIN = -Wno-address-of-packed-member -static
|
||||||
LIBS_LINUX = -lnetfilter_queue -lnfnetlink -lz
|
LIBS_LINUX = -lnetfilter_queue -lnfnetlink -lz
|
||||||
|
LIBS_SYSTEMD = -lsystemd
|
||||||
LIBS_BSD = -lz
|
LIBS_BSD = -lz
|
||||||
LIBS_CYGWIN = -lz -Lwindows/windivert -Iwindows -lwlanapi -lole32 -loleaut32
|
LIBS_CYGWIN = -lz -Lwindows/windivert -Iwindows -lwlanapi -lole32 -loleaut32
|
||||||
LIBS_CYGWIN32 = -lwindivert32
|
LIBS_CYGWIN32 = -lwindivert32
|
||||||
@ -15,24 +16,27 @@ SRC_FILES = *.c crypto/*.c
|
|||||||
all: nfqws
|
all: nfqws
|
||||||
|
|
||||||
nfqws: $(SRC_FILES)
|
nfqws: $(SRC_FILES)
|
||||||
$(CC) -s $(CFLAGS) -o nfqws $(SRC_FILES) $(LDFLAGS) $(LIBS_LINUX)
|
$(CC) -s $(CFLAGS) -o nfqws $(SRC_FILES) $(LIBS_LINUX) $(LDFLAGS)
|
||||||
|
|
||||||
|
systemd: $(SRC_FILES)
|
||||||
|
$(CC) -s $(CFLAGS) $(CFLAGS_SYSTEMD) -o nfqws $(SRC_FILES) $(LIBS_LINUX) $(LIBS_SYSTEMD) $(LDFLAGS)
|
||||||
|
|
||||||
android: nfqws
|
android: nfqws
|
||||||
|
|
||||||
bsd: $(SRC_FILES)
|
bsd: $(SRC_FILES)
|
||||||
$(CC) -s $(CFLAGS) $(CFLAGS_BSD) -o dvtws $(SRC_FILES) $(LDFLAGS) $(LIBS_BSD)
|
$(CC) -s $(CFLAGS) $(CFLAGS_BSD) -o dvtws $(SRC_FILES) $(LIBS_BSD) $(LDFLAGS)
|
||||||
|
|
||||||
mac: $(SRC_FILES)
|
mac: $(SRC_FILES)
|
||||||
$(CC) $(CFLAGS) $(CFLAGS_BSD) -o dvtwsa $(SRC_FILES) $(LDFLAGS) -target arm64-apple-macos10.8 $(LIBS_BSD)
|
$(CC) $(CFLAGS) $(CFLAGS_BSD) -o dvtwsa $(SRC_FILES) -target arm64-apple-macos10.8 $(LIBS_BSD) $(LDFLAGS)
|
||||||
$(CC) $(CFLAGS) $(CFLAGS_BSD) -o dvtwsx $(SRC_FILES) $(LDFLAGS) -target x86_64-apple-macos10.8 $(LIBS_BSD)
|
$(CC) $(CFLAGS) $(CFLAGS_BSD) -o dvtwsx $(SRC_FILES) -target x86_64-apple-macos10.8 $(LIBS_BSD) $(LDFLAGS)
|
||||||
strip dvtwsa dvtwsx
|
strip dvtwsa dvtwsx
|
||||||
lipo -create -output dvtws dvtwsx dvtwsa
|
lipo -create -output dvtws dvtwsx dvtwsa
|
||||||
rm -f dvtwsx dvtwsa
|
rm -f dvtwsx dvtwsa
|
||||||
|
|
||||||
cygwin64:
|
cygwin64:
|
||||||
$(CC) -s $(CFLAGS) $(CFLAGS_CYGWIN) -o winws $(SRC_FILES) $(LDFLAGS) $(LIBS_CYGWIN) $(LIBS_CYGWIN64) $(RES_CYGWIN64)
|
$(CC) -s $(CFLAGS) $(CFLAGS_CYGWIN) -o winws $(SRC_FILES) $(LIBS_CYGWIN) $(LIBS_CYGWIN64) $(RES_CYGWIN64) $(LDFLAGS)
|
||||||
cygwin32:
|
cygwin32:
|
||||||
$(CC) -s $(CFLAGS) $(CFLAGS_CYGWIN) -o winws $(SRC_FILES) $(LDFLAGS) $(LIBS_CYGWIN) $(LIBS_CYGWIN32) $(RES_CYGWIN32)
|
$(CC) -s $(CFLAGS) $(CFLAGS_CYGWIN) -o winws $(SRC_FILES) $(LIBS_CYGWIN) $(LIBS_CYGWIN32) $(RES_CYGWIN32) $(LDFLAGS)
|
||||||
cygwin: cygwin64
|
cygwin: cygwin64
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
@ -27,11 +27,8 @@ static void connswap(const t_conn *c, t_conn *c2)
|
|||||||
|
|
||||||
void ConntrackClearHostname(t_ctrack *track)
|
void ConntrackClearHostname(t_ctrack *track)
|
||||||
{
|
{
|
||||||
if (track->hostname)
|
free(track->hostname);
|
||||||
{
|
track->hostname = NULL;
|
||||||
free(track->hostname);
|
|
||||||
track->hostname = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
static void ConntrackClearTrack(t_ctrack *track)
|
static void ConntrackClearTrack(t_ctrack *track)
|
||||||
{
|
{
|
||||||
@ -349,11 +346,8 @@ void ConntrackPoolDump(const t_conntrack *p)
|
|||||||
|
|
||||||
void ReasmClear(t_reassemble *reasm)
|
void ReasmClear(t_reassemble *reasm)
|
||||||
{
|
{
|
||||||
if (reasm->packet)
|
free(reasm->packet);
|
||||||
{
|
reasm->packet = NULL;
|
||||||
free(reasm->packet);
|
|
||||||
reasm->packet = NULL;
|
|
||||||
}
|
|
||||||
reasm->size = reasm->size_present = 0;
|
reasm->size = reasm->size_present = 0;
|
||||||
}
|
}
|
||||||
bool ReasmInit(t_reassemble *reasm, size_t size_requested, uint32_t seq_start)
|
bool ReasmInit(t_reassemble *reasm, size_t size_requested, uint32_t seq_start)
|
||||||
|
@ -1747,7 +1747,9 @@ nofix:
|
|||||||
bytes = sendto(sock, data, len, 0, (struct sockaddr*)&dst2, salen);
|
bytes = sendto(sock, data, len, 0, (struct sockaddr*)&dst2, salen);
|
||||||
if (bytes==-1)
|
if (bytes==-1)
|
||||||
{
|
{
|
||||||
DLOG_PERROR("rawsend: sendto");
|
char s[40];
|
||||||
|
snprintf(s,sizeof(s),"rawsend: sendto (%zu)",len);
|
||||||
|
DLOG_PERROR(s);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
640
nfq/desync.c
640
nfq/desync.c
@ -16,71 +16,146 @@ const char *fake_http_request_default = "GET / HTTP/1.1\r\nHost: www.iana.org\r\
|
|||||||
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\n"
|
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\n"
|
||||||
"Accept-Encoding: gzip, deflate, br\r\n\r\n";
|
"Accept-Encoding: gzip, deflate, br\r\n\r\n";
|
||||||
|
|
||||||
// random : +11 size 32
|
// SNI - www.microsoft.com
|
||||||
// random : +44 size 32
|
const uint8_t fake_tls_clienthello_default[680] = {
|
||||||
// sni : gatech.edu +125 size 11
|
0x16, 0x03, 0x01, 0x02, 0xa3, 0x01, 0x00, 0x02, 0x9f, 0x03, 0x03, 0x41,
|
||||||
const uint8_t fake_tls_clienthello_default[648] = {
|
0x88, 0x82, 0x2d, 0x4f, 0xfd, 0x81, 0x48, 0x9e, 0xe7, 0x90, 0x65, 0x1f,
|
||||||
0x16,0x03,0x01,0x02,0x83,0x01,0x00,0x02,0x7f,0x03,0x03,0x98,0xfb,0x69,0x1d,0x31,
|
0xba, 0x05, 0x7b, 0xff, 0xa7, 0x5a, 0xf9, 0x5b, 0x8a, 0x8f, 0x45, 0x8b,
|
||||||
0x66,0xc4,0xd8,0x07,0x25,0x2b,0x74,0x47,0x01,0x44,0x09,0x08,0xcf,0x13,0x67,0xe0,
|
0x41, 0xf0, 0x3d, 0x1b, 0xdd, 0xe3, 0xf8, 0x20, 0x9b, 0x23, 0xa5, 0xd2,
|
||||||
0x46,0x19,0x1f,0xcb,0xee,0xe6,0x8e,0x33,0xb9,0x91,0xa0,0x20,0xf2,0xed,0x56,0x73,
|
0x21, 0x1e, 0x9f, 0xe7, 0x85, 0x6c, 0xfc, 0x61, 0x80, 0x3a, 0x3f, 0xba,
|
||||||
0xa4,0x0a,0xce,0xa6,0xad,0xd2,0xfd,0x71,0xb8,0xb9,0xfd,0x06,0x0e,0xdd,0xf0,0x57,
|
0xb9, 0x60, 0xba, 0xb3, 0x0e, 0x98, 0x27, 0x6c, 0xf7, 0x38, 0x28, 0x65,
|
||||||
0x37,0x7d,0x96,0xb5,0x80,0x6e,0x54,0xe2,0x15,0xce,0x5f,0xff,0x00,0x22,0x13,0x01,
|
0x80, 0x5d, 0x40, 0x38, 0x00, 0x22, 0x13, 0x01, 0x13, 0x03, 0x13, 0x02,
|
||||||
0x13,0x03,0x13,0x02,0xc0,0x2b,0xc0,0x2f,0xcc,0xa9,0xcc,0xa8,0xc0,0x2c,0xc0,0x30,
|
0xc0, 0x2b, 0xc0, 0x2f, 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x2c, 0xc0, 0x30,
|
||||||
0xc0,0x0a,0xc0,0x09,0xc0,0x13,0xc0,0x14,0x00,0x9c,0x00,0x9d,0x00,0x2f,0x00,0x35,
|
0xc0, 0x0a, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d,
|
||||||
0x01,0x00,0x02,0x14,0x00,0x00,0x00,0x0f,0x00,0x0d,0x00,0x00,0x0a,0x67,0x61,0x74,
|
0x00, 0x2f, 0x00, 0x35, 0x01, 0x00, 0x02, 0x34, 0x00, 0x00, 0x00, 0x16,
|
||||||
0x65,0x63,0x68,0x2e,0x65,0x64,0x75,0x00,0x17,0x00,0x00,0xff,0x01,0x00,0x01,0x00,
|
0x00, 0x14, 0x00, 0x00, 0x11, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63,
|
||||||
0x00,0x0a,0x00,0x0e,0x00,0x0c,0x00,0x1d,0x00,0x17,0x00,0x18,0x00,0x19,0x01,0x00,
|
0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x17,
|
||||||
0x01,0x01,0x00,0x0b,0x00,0x02,0x01,0x00,0x00,0x10,0x00,0x0e,0x00,0x0c,0x02,0x68,
|
0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x0e, 0x00,
|
||||||
0x32,0x08,0x68,0x74,0x74,0x70,0x2f,0x31,0x2e,0x31,0x00,0x05,0x00,0x05,0x01,0x00,
|
0x0c, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x01, 0x00, 0x01,
|
||||||
0x00,0x00,0x00,0x00,0x22,0x00,0x0a,0x00,0x08,0x04,0x03,0x05,0x03,0x06,0x03,0x02,
|
0x01, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
|
||||||
0x03,0x00,0x33,0x00,0x6b,0x00,0x69,0x00,0x1d,0x00,0x20,0x72,0xe5,0xce,0x58,0x31,
|
0x10, 0x00, 0x0e, 0x00, 0x0c, 0x02, 0x68, 0x32, 0x08, 0x68, 0x74, 0x74,
|
||||||
0x3c,0x08,0xaa,0x2f,0xa8,0x40,0xe7,0x7a,0xdf,0x46,0x5b,0x63,0x62,0xc7,0xfa,0x49,
|
0x70, 0x2f, 0x31, 0x2e, 0x31, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00,
|
||||||
0x18,0xac,0xa1,0x00,0x7c,0x42,0xc5,0x02,0x94,0x5c,0x44,0x00,0x17,0x00,0x41,0x04,
|
0x00, 0x00, 0x00, 0x22, 0x00, 0x0a, 0x00, 0x08, 0x04, 0x03, 0x05, 0x03,
|
||||||
0x8f,0x3e,0x5f,0xd4,0x7f,0x37,0x47,0xd3,0x33,0x70,0x38,0x7f,0x11,0x35,0xc1,0x55,
|
0x06, 0x03, 0x02, 0x03, 0x00, 0x12, 0x00, 0x00, 0x00, 0x33, 0x00, 0x6b,
|
||||||
0x8a,0x6c,0xc7,0x5a,0xd4,0xf7,0x31,0xbb,0x9e,0xee,0xd1,0x8f,0x74,0xdd,0x9b,0xbb,
|
0x00, 0x69, 0x00, 0x1d, 0x00, 0x20, 0x69, 0x15, 0x16, 0x29, 0x6d, 0xad,
|
||||||
0x91,0xa1,0x72,0xda,0xeb,0xf6,0xc6,0x82,0x84,0xfe,0xb7,0xfd,0x7b,0xe1,0x9f,0xd2,
|
0xd5, 0x68, 0x88, 0x27, 0x2f, 0xde, 0xaf, 0xac, 0x3c, 0x4c, 0xa4, 0xe4,
|
||||||
0xb9,0x3e,0x83,0xa6,0x9c,0xac,0x81,0xe2,0x00,0xd5,0x19,0x55,0x91,0xa7,0x0c,0x29,
|
0xd8, 0xc8, 0xfb, 0x41, 0x87, 0xf4, 0x76, 0x4e, 0x0e, 0xfa, 0x64, 0xc4,
|
||||||
0x00,0x2b,0x00,0x05,0x04,0x03,0x04,0x03,0x03,0x00,0x0d,0x00,0x18,0x00,0x16,0x04,
|
0xe9, 0x29, 0x00, 0x17, 0x00, 0x41, 0x04, 0xfe, 0x62, 0xb9, 0x08, 0xc8,
|
||||||
0x03,0x05,0x03,0x06,0x03,0x08,0x04,0x08,0x05,0x08,0x06,0x04,0x01,0x05,0x01,0x06,
|
0xc3, 0x2a, 0xb9, 0x87, 0x37, 0x84, 0x42, 0x6b, 0x5c, 0xcd, 0xc9, 0xca,
|
||||||
0x01,0x02,0x03,0x02,0x01,0x00,0x1c,0x00,0x02,0x40,0x01,0xfe,0x0d,0x01,0x19,0x00,
|
0x62, 0x38, 0xd3, 0xd9, 0x99, 0x8a, 0xc4, 0x2d, 0xc6, 0xd0, 0xa3, 0x60,
|
||||||
0x00,0x01,0x00,0x01,0xfe,0x00,0x20,0xae,0x8b,0x30,0x3c,0xf0,0xa9,0x0d,0xa1,0x69,
|
0xb2, 0x12, 0x54, 0x41, 0x8e, 0x52, 0x5e, 0xe3, 0xab, 0xf9, 0xc2, 0x07,
|
||||||
0x95,0xb8,0xe2,0xed,0x08,0x6d,0x48,0xdf,0xf7,0x5b,0x9d,0x66,0xef,0x15,0x97,0xbc,
|
0x81, 0xdc, 0xf8, 0xf2, 0x6a, 0x91, 0x40, 0x2f, 0xcb, 0xa4, 0xff, 0x6f,
|
||||||
0x2c,0x99,0x91,0x12,0x7a,0x35,0xd0,0x00,0xef,0xb1,0x8d,0xff,0x61,0x57,0x52,0xef,
|
0x24, 0xc7, 0x4d, 0x77, 0x77, 0x2d, 0x6f, 0xe0, 0x77, 0xaa, 0x92, 0x00,
|
||||||
0xd6,0xea,0xbf,0xf3,0x6d,0x78,0x14,0x38,0xff,0xeb,0x58,0xe8,0x9d,0x59,0x4b,0xd5,
|
0x2b, 0x00, 0x05, 0x04, 0x03, 0x04, 0x03, 0x03, 0x00, 0x0d, 0x00, 0x18,
|
||||||
0x9f,0x59,0x12,0xf9,0x03,0x9a,0x20,0x37,0x85,0x77,0xb1,0x4c,0xd8,0xef,0xa6,0xc8,
|
0x00, 0x16, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x08, 0x04, 0x08, 0x05,
|
||||||
0x54,0x8d,0x07,0x27,0x95,0xce,0xd5,0x37,0x4d,0x69,0x18,0xd4,0xfd,0x5e,0xdf,0x64,
|
0x08, 0x06, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x02, 0x03, 0x02, 0x01,
|
||||||
0xcc,0x10,0x2f,0x7f,0x0e,0xc9,0xfd,0xd4,0xd0,0x18,0x61,0x1b,0x57,0x8f,0x41,0x7f,
|
0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x1c, 0x00, 0x02, 0x40, 0x01,
|
||||||
0x6f,0x4f,0x5c,0xad,0x04,0xc6,0x5e,0x74,0x54,0x87,0xba,0x28,0xe6,0x11,0x0b,0x9d,
|
0x00, 0x1b, 0x00, 0x07, 0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0xfe,
|
||||||
0x3f,0x0b,0x6d,0xf4,0x2d,0xfc,0x31,0x4e,0xfd,0x49,0xe7,0x15,0x96,0xaf,0xee,0x9a,
|
0x0d, 0x01, 0x19, 0x00, 0x00, 0x01, 0x00, 0x03, 0x21, 0x00, 0x20, 0x62,
|
||||||
0x48,0x1b,0xae,0x5e,0x7c,0x20,0xbe,0xb4,0xec,0x68,0xb6,0x74,0x22,0xa0,0xec,0xff,
|
0xe8, 0x83, 0xd8, 0x97, 0x05, 0x8a, 0xbe, 0xa1, 0xf2, 0x63, 0x4e, 0xce,
|
||||||
0x19,0x96,0xe4,0x10,0x8f,0x3c,0x91,0x88,0xa1,0xcc,0x78,0xef,0x4e,0x0e,0xe3,0xb6,
|
0x93, 0x84, 0x8e, 0xcf, 0xe7, 0xdd, 0xb2, 0xe4, 0x87, 0x06, 0xac, 0x11,
|
||||||
0x57,0x8c,0x33,0xef,0xaa,0xb0,0x1d,0x45,0x1c,0x02,0x4c,0xe2,0x80,0x30,0xe8,0x48,
|
0x19, 0xbe, 0x0e, 0x71, 0x87, 0xf1, 0xa6, 0x00, 0xef, 0xd8, 0x6b, 0x27,
|
||||||
0x7a,0x09,0x71,0x94,0x7c,0xb6,0x75,0x81,0x1c,0xae,0xe3,0x3f,0xde,0xea,0x2b,0x45,
|
0x5e, 0xc0, 0xa7, 0x5d, 0x42, 0x4e, 0x8c, 0xdc, 0xf3, 0x9f, 0x1c, 0x51,
|
||||||
0xcc,0xe3,0x64,0x09,0xf7,0x60,0x26,0x0c,0x7d,0xad,0x55,0x65,0xb6,0xf5,0x85,0x04,
|
0x62, 0xef, 0xff, 0x5b, 0xed, 0xc8, 0xfd, 0xee, 0x6f, 0xbb, 0x88, 0x9b,
|
||||||
0x64,0x2f,0x97,0xd0,0x6a,0x06,0x36,0xcd,0x25,0xda,0x51,0xab,0xd6,0xf7,0x5e,0xeb,
|
0xb1, 0x30, 0x9c, 0x66, 0x42, 0xab, 0x0f, 0x66, 0x89, 0x18, 0x8b, 0x11,
|
||||||
0xd4,0x03,0x39,0xa4,0xc4,0x2a,0x9c,0x17,0xe8,0xb0,0x9f,0xc0,0xd3,0x8c,0x76,0xdd,
|
0xc1, 0x6d, 0xe7, 0x2a, 0xeb, 0x96, 0x3b, 0x7f, 0x52, 0x78, 0xdb, 0xf8,
|
||||||
0xa1,0x0b,0x76,0x9f,0x23,0xfa,0xed,0xfb,0xd7,0x78,0x0f,0x00,0xf7,0x45,0x03,0x04,
|
0x6d, 0x04, 0xf7, 0x95, 0x1a, 0xa8, 0xf0, 0x64, 0x52, 0x07, 0x39, 0xf0,
|
||||||
0x84,0x66,0x6b,0xec,0xc7,0xed,0xbc,0xe4
|
0xa8, 0x1d, 0x0d, 0x16, 0x36, 0xb7, 0x18, 0x0e, 0xc8, 0x44, 0x27, 0xfe,
|
||||||
|
0xf3, 0x31, 0xf0, 0xde, 0x8c, 0x74, 0xf5, 0xa1, 0xd8, 0x8f, 0x6f, 0x45,
|
||||||
|
0x97, 0x69, 0x79, 0x5e, 0x2e, 0xd4, 0xb0, 0x2c, 0x0c, 0x1a, 0x6f, 0xcc,
|
||||||
|
0xce, 0x90, 0xc7, 0xdd, 0xc6, 0x60, 0x95, 0xf3, 0xc2, 0x19, 0xde, 0x50,
|
||||||
|
0x80, 0xbf, 0xde, 0xf2, 0x25, 0x63, 0x15, 0x26, 0x63, 0x09, 0x1f, 0xc5,
|
||||||
|
0xdf, 0x32, 0xf5, 0xea, 0x9c, 0xd2, 0xff, 0x99, 0x4e, 0x67, 0xa2, 0xe5,
|
||||||
|
0x1a, 0x94, 0x85, 0xe3, 0xdf, 0x36, 0xa5, 0x83, 0x4b, 0x0a, 0x1c, 0xaf,
|
||||||
|
0xd7, 0x48, 0xc9, 0x4b, 0x8a, 0x27, 0xdd, 0x58, 0x7f, 0x95, 0xf2, 0x6b,
|
||||||
|
0xde, 0x2b, 0x12, 0xd3, 0xec, 0x4d, 0x69, 0x37, 0x9c, 0x13, 0x9b, 0x16,
|
||||||
|
0xb0, 0x45, 0x52, 0x38, 0x77, 0x69, 0xef, 0xaa, 0x65, 0x19, 0xbc, 0xc2,
|
||||||
|
0x93, 0x4d, 0xb0, 0x1b, 0x7f, 0x5b, 0x41, 0xff, 0xaf, 0xba, 0x50, 0x51,
|
||||||
|
0xc3, 0xf1, 0x27, 0x09, 0x25, 0xf5, 0x60, 0x90, 0x09, 0xb1, 0xe5, 0xc0,
|
||||||
|
0xc7, 0x42, 0x78, 0x54, 0x3b, 0x23, 0x19, 0x7d, 0x8e, 0x72, 0x13, 0xb4,
|
||||||
|
0xd3, 0xcd, 0x63, 0xb6, 0xc4, 0x4a, 0x28, 0x3d, 0x45, 0x3e, 0x8b, 0xdb,
|
||||||
|
0x84, 0x4f, 0x78, 0x64, 0x30, 0x69, 0xe2, 0x1b
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char * tld[]={"com","org","net","edu","gov","biz"};
|
|
||||||
void randomize_default_tls_payload(uint8_t *p)
|
|
||||||
{
|
|
||||||
fill_random_bytes(p+11,32);
|
|
||||||
fill_random_bytes(p+44,32);
|
|
||||||
fill_random_az(p+125,1);
|
|
||||||
fill_random_az09(p+126,5);
|
|
||||||
memcpy(p+132,tld[random()%(sizeof(tld)/sizeof(*tld))],3);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PKTDATA_MAXDUMP 32
|
#define PKTDATA_MAXDUMP 32
|
||||||
#define IP_MAXDUMP 80
|
#define IP_MAXDUMP 80
|
||||||
|
|
||||||
static uint8_t zeropkt[DPI_DESYNC_MAX_FAKE_LEN];
|
#define TCP_MAX_REASM 16384
|
||||||
|
#define UDP_MAX_REASM 16384
|
||||||
|
|
||||||
void desync_init(void)
|
static void TLSDebugHandshake(const uint8_t *tls,size_t sz)
|
||||||
{
|
{
|
||||||
memset(zeropkt, 0, sizeof(zeropkt));
|
if (!params.debug) return;
|
||||||
|
|
||||||
|
if (sz<6) return;
|
||||||
|
|
||||||
|
const uint8_t *ext;
|
||||||
|
size_t len,len2;
|
||||||
|
|
||||||
|
uint16_t v_handshake=pntoh16(tls+4), v, v2;
|
||||||
|
DLOG("TLS handshake version : %s\n",TLSVersionStr(v_handshake));
|
||||||
|
|
||||||
|
if (TLSFindExtInHandshake(tls,sz,43,&ext,&len,false))
|
||||||
|
{
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
len2 = ext[0];
|
||||||
|
if (len2<len)
|
||||||
|
{
|
||||||
|
for(ext++,len2&=~1 ; len2 ; len2-=2,ext+=2)
|
||||||
|
{
|
||||||
|
v = pntoh16(ext);
|
||||||
|
DLOG("TLS supported versions ext : %s\n",TLSVersionStr(v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DLOG("TLS supported versions ext : not present\n");
|
||||||
|
|
||||||
|
if (TLSFindExtInHandshake(tls,sz,16,&ext,&len,false))
|
||||||
|
{
|
||||||
|
if (len>=2)
|
||||||
|
{
|
||||||
|
len2 = pntoh16(ext);
|
||||||
|
if (len2<=(len-2))
|
||||||
|
{
|
||||||
|
char s[32];
|
||||||
|
for(ext+=2; len2 ;)
|
||||||
|
{
|
||||||
|
v = *ext; ext++; len2--;
|
||||||
|
if (v<=len2)
|
||||||
|
{
|
||||||
|
v2 = v<sizeof(s) ? v : sizeof(s)-1;
|
||||||
|
memcpy(s,ext,v2);
|
||||||
|
s[v2]=0;
|
||||||
|
DLOG("TLS ALPN ext : %s\n",s);
|
||||||
|
len2-=v;
|
||||||
|
ext+=v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DLOG("TLS ALPN ext : not present\n");
|
||||||
|
|
||||||
|
DLOG("TLS ECH ext : %s\n",TLSFindExtInHandshake(tls,sz,65037,NULL,NULL,false) ? "present" : "not present");
|
||||||
|
}
|
||||||
|
static void TLSDebug(const uint8_t *tls,size_t sz)
|
||||||
|
{
|
||||||
|
if (!params.debug) return;
|
||||||
|
|
||||||
|
if (sz<11) return;
|
||||||
|
|
||||||
|
DLOG("TLS record layer version : %s\n",TLSVersionStr(pntoh16(tls+1)));
|
||||||
|
|
||||||
|
size_t reclen=TLSRecordLen(tls);
|
||||||
|
if (reclen<sz) sz=reclen; // correct len if it has more data than the first tls record has
|
||||||
|
|
||||||
|
TLSDebugHandshake(tls+5,sz-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool desync_valid_zero_stage(enum dpi_desync_mode mode)
|
bool desync_valid_zero_stage(enum dpi_desync_mode mode)
|
||||||
@ -364,17 +439,18 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname
|
|||||||
{
|
{
|
||||||
DLOG("auto hostlist (profile %d) : adding %s to %s\n", dp->n, hostname, dp->hostlist_auto->filename);
|
DLOG("auto hostlist (profile %d) : adding %s to %s\n", dp->n, hostname, dp->hostlist_auto->filename);
|
||||||
HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : adding to %s", hostname, dp->n, client_ip_port, l7proto_str(l7proto), dp->hostlist_auto->filename);
|
HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : adding to %s", hostname, dp->n, client_ip_port, l7proto_str(l7proto), dp->hostlist_auto->filename);
|
||||||
if (!StrPoolAddStr(&dp->hostlist_auto->hostlist, hostname))
|
if (!HostlistPoolAddStr(&dp->hostlist_auto->hostlist, hostname, 0))
|
||||||
{
|
{
|
||||||
DLOG_ERR("StrPoolAddStr out of memory\n");
|
DLOG_ERR("StrPoolAddStr out of memory\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!append_to_list_file(dp->hostlist_auto->filename, hostname))
|
if (!append_to_list_file(dp->hostlist_auto->filename, hostname))
|
||||||
{
|
{
|
||||||
DLOG_PERROR("write to auto hostlist:");
|
DLOG_PERROR("write to auto hostlist");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dp->hostlist_auto->mod_time = file_mod_time(dp->hostlist_auto->filename);
|
if (!file_mod_signature(dp->hostlist_auto->filename, &dp->hostlist_auto->mod_sig))
|
||||||
|
DLOG_PERROR("file_mod_signature");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -619,6 +695,61 @@ static uint16_t IP4_IP_ID_FIX(const struct ip *ip)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// fake_mod buffer must at least sizeof(desync_profile->fake_tls)
|
||||||
|
// size does not change
|
||||||
|
// return : true - altered, false - not altered
|
||||||
|
static bool runtime_tls_mod(int fake_n,const struct fake_tls_mod_cache *modcache, const struct fake_tls_mod *tls_mod, const uint8_t *fake_data, size_t fake_data_size, const uint8_t *payload, size_t payload_len, uint8_t *fake_mod)
|
||||||
|
{
|
||||||
|
bool b=false;
|
||||||
|
if (modcache) // it's filled only if it's TLS
|
||||||
|
{
|
||||||
|
if (tls_mod->mod & FAKE_TLS_MOD_PADENCAP)
|
||||||
|
{
|
||||||
|
size_t sz_rec = pntoh16(fake_data+3) + payload_len;
|
||||||
|
size_t sz_handshake = pntoh24(fake_data+6) + payload_len;
|
||||||
|
size_t sz_ext = pntoh16(fake_data+modcache->extlen_offset) + payload_len;
|
||||||
|
size_t sz_pad = pntoh16(fake_data+modcache->padlen_offset) + payload_len;
|
||||||
|
if ((sz_rec & ~0xFFFF) || (sz_handshake & ~0xFFFFFF) || (sz_ext & ~0xFFFF) || (sz_pad & ~0xFFFF))
|
||||||
|
DLOG("fake[%d] cannot apply padencap tls mod. length overflow.\n", fake_n);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(fake_mod,fake_data,fake_data_size);
|
||||||
|
phton16(fake_mod+3,(uint16_t)sz_rec);
|
||||||
|
phton24(fake_mod+6,(uint32_t)sz_handshake);
|
||||||
|
phton16(fake_mod+modcache->extlen_offset,(uint16_t)sz_ext);
|
||||||
|
phton16(fake_mod+modcache->padlen_offset,(uint16_t)sz_pad);
|
||||||
|
b=true;
|
||||||
|
DLOG("fake[%d] applied padencap tls mod. sizes increased by %zu bytes.\n", fake_n, payload_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tls_mod->mod & FAKE_TLS_MOD_RND)
|
||||||
|
{
|
||||||
|
if (!b) memcpy(fake_mod,fake_data,fake_data_size);
|
||||||
|
fill_random_bytes(fake_mod+11,32); // random
|
||||||
|
fill_random_bytes(fake_mod+44,fake_mod[43]); // session id
|
||||||
|
b=true;
|
||||||
|
DLOG("fake[%d] applied rnd tls mod\n", fake_n);
|
||||||
|
}
|
||||||
|
if (tls_mod->mod & FAKE_TLS_MOD_DUP_SID)
|
||||||
|
{
|
||||||
|
if (payload_len<44)
|
||||||
|
DLOG("fake[%d] cannot apply dupsid tls mod. data payload is too short.\n",fake_n);
|
||||||
|
else if (fake_data[43]!=payload[43])
|
||||||
|
DLOG("fake[%d] cannot apply dupsid tls mod. fake and orig session id length mismatch.\n",fake_n);
|
||||||
|
else if (payload_len<(44+payload[43]))
|
||||||
|
DLOG("fake[%d] cannot apply dupsid tls mod. data payload is not valid.\n",fake_n);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!b) memcpy(fake_mod,fake_data,fake_data_size);
|
||||||
|
memcpy(fake_mod+44,payload+44,fake_mod[43]); // session id
|
||||||
|
b=true;
|
||||||
|
DLOG("fake[%d] applied dupsid tls mod\n", fake_n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint32_t fwmark, const char *ifout, struct dissect *dis)
|
static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint32_t fwmark, const char *ifout, struct dissect *dis)
|
||||||
{
|
{
|
||||||
uint8_t verdict=VERDICT_PASS;
|
uint8_t verdict=VERDICT_PASS;
|
||||||
@ -849,8 +980,8 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
|
|
||||||
if (!(dis->tcp->th_flags & TH_SYN) && dis->len_payload)
|
if (!(dis->tcp->th_flags & TH_SYN) && dis->len_payload)
|
||||||
{
|
{
|
||||||
const uint8_t *fake;
|
struct blob_collection_head *fake;
|
||||||
size_t fake_size;
|
|
||||||
char host[256];
|
char host[256];
|
||||||
bool bHaveHost=false;
|
bool bHaveHost=false;
|
||||||
uint8_t *p, *phost=NULL;
|
uint8_t *p, *phost=NULL;
|
||||||
@ -910,6 +1041,8 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
DLOG(bReqFull ? "packet contains full TLS ClientHello\n" : "packet contains partial TLS ClientHello\n");
|
DLOG(bReqFull ? "packet contains full TLS ClientHello\n" : "packet contains partial TLS ClientHello\n");
|
||||||
l7proto = TLS;
|
l7proto = TLS;
|
||||||
|
|
||||||
|
if (bReqFull) TLSDebug(rdata_payload,rlen_payload);
|
||||||
|
|
||||||
bHaveHost=TLSHelloExtractHost(rdata_payload,rlen_payload,host,sizeof(host),TLS_PARTIALS_ENABLE);
|
bHaveHost=TLSHelloExtractHost(rdata_payload,rlen_payload,host,sizeof(host),TLS_PARTIALS_ENABLE);
|
||||||
|
|
||||||
if (ctrack)
|
if (ctrack)
|
||||||
@ -920,7 +1053,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
!(ctrack->req_seq_finalized && seq_within(ctrack->seq_last, ctrack->req_seq_start, ctrack->req_seq_end)))
|
!(ctrack->req_seq_finalized && seq_within(ctrack->seq_last, ctrack->req_seq_start, ctrack->req_seq_end)))
|
||||||
{
|
{
|
||||||
// do not reconstruct unexpected large payload (they are feeding garbage ?)
|
// do not reconstruct unexpected large payload (they are feeding garbage ?)
|
||||||
if (!reasm_orig_start(ctrack,IPPROTO_TCP,TLSRecordLen(dis->data_payload),16384,dis->data_payload,dis->len_payload))
|
if (!reasm_orig_start(ctrack,IPPROTO_TCP,TLSRecordLen(dis->data_payload),TCP_MAX_REASM,dis->data_payload,dis->len_payload))
|
||||||
{
|
{
|
||||||
reasm_orig_cancel(ctrack);
|
reasm_orig_cancel(ctrack);
|
||||||
return verdict;
|
return verdict;
|
||||||
@ -1082,7 +1215,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
}
|
}
|
||||||
|
|
||||||
ttl_fake = (ctrack_replay && ctrack_replay->autottl) ? ctrack_replay->autottl : (dis->ip6 ? (dp->desync_ttl6 ? dp->desync_ttl6 : ttl_orig) : (dp->desync_ttl ? dp->desync_ttl : ttl_orig));
|
ttl_fake = (ctrack_replay && ctrack_replay->autottl) ? ctrack_replay->autottl : (dis->ip6 ? (dp->desync_ttl6 ? dp->desync_ttl6 : ttl_orig) : (dp->desync_ttl ? dp->desync_ttl : ttl_orig));
|
||||||
if ((l7proto == HTTP) && (dp->hostcase || dp->hostnospace || dp->domcase) && HttpFindHost(&phost,dis->data_payload,dis->len_payload))
|
if ((l7proto == HTTP) && (dp->hostcase || dp->hostnospace || dp->domcase || dp->methodeol) && HttpFindHost(&phost,dis->data_payload,dis->len_payload))
|
||||||
{
|
{
|
||||||
if (dp->hostcase)
|
if (dp->hostcase)
|
||||||
{
|
{
|
||||||
@ -1098,23 +1231,40 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
verdict=VERDICT_MODIFY;
|
verdict=VERDICT_MODIFY;
|
||||||
}
|
}
|
||||||
uint8_t *pua;
|
uint8_t *pua;
|
||||||
if (dp->hostnospace &&
|
if (dp->hostnospace)
|
||||||
(pua = (uint8_t*)memmem(dis->data_payload, dis->len_payload, "\r\nUser-Agent: ", 14)) &&
|
|
||||||
(pua = (uint8_t*)memmem(pua + 1, dis->len_payload - (pua - dis->data_payload) - 1, "\r\n", 2)))
|
|
||||||
{
|
{
|
||||||
DLOG("removing space after Host: and adding it to User-Agent:\n");
|
if ((pua = (uint8_t*)memmem(dis->data_payload, dis->len_payload, "\r\nUser-Agent: ", 14)) &&
|
||||||
if (pua > phost)
|
(pua = (uint8_t*)memmem(pua + 1, dis->len_payload - (pua - dis->data_payload) - 1, "\r\n", 2)))
|
||||||
{
|
{
|
||||||
memmove(phost + 5, phost + 6, pua - phost - 6);
|
DLOG("removing space after Host: and adding it to User-Agent:\n");
|
||||||
pua[-1]=' ';
|
if (pua > phost)
|
||||||
|
{
|
||||||
|
memmove(phost + 5, phost + 6, pua - phost - 6);
|
||||||
|
pua[-1]=' ';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memmove(pua + 1, pua, phost - pua + 5);
|
||||||
|
*pua = ' ';
|
||||||
|
}
|
||||||
|
verdict=VERDICT_MODIFY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
DLOG("cannot do hostnospace because valid User-Agent: not found\n");
|
||||||
memmove(pua + 1, pua, phost - pua + 5);
|
|
||||||
*pua = ' ';
|
|
||||||
}
|
|
||||||
verdict=VERDICT_MODIFY;
|
|
||||||
}
|
}
|
||||||
|
else if (dp->methodeol)
|
||||||
|
{
|
||||||
|
if (phost[5]==' ' || phost[5]=='\t')
|
||||||
|
{
|
||||||
|
DLOG("removing space after Host: and adding '\\n' before method\n");
|
||||||
|
memmove(dis->data_payload+1,dis->data_payload,phost-dis->data_payload+5);
|
||||||
|
dis->data_payload[0]='\n';
|
||||||
|
verdict=VERDICT_MODIFY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DLOG("cannot do methodeol because there's no space or tab after Host:\n");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dp->desync_mode==DESYNC_NONE)
|
if (dp->desync_mode==DESYNC_NONE)
|
||||||
@ -1134,16 +1284,13 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
switch(l7proto)
|
switch(l7proto)
|
||||||
{
|
{
|
||||||
case HTTP:
|
case HTTP:
|
||||||
fake = dp->fake_http;
|
fake = &dp->fake_http;
|
||||||
fake_size = dp->fake_http_size;
|
|
||||||
break;
|
break;
|
||||||
case TLS:
|
case TLS:
|
||||||
fake = dp->fake_tls;
|
fake = &dp->fake_tls;
|
||||||
fake_size = dp->fake_tls_size;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fake = dp->fake_unknown;
|
fake = &dp->fake_unknown;
|
||||||
fake_size = dp->fake_unknown_size;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (dp->desync_mode==DESYNC_MULTISPLIT || dp->desync_mode==DESYNC_MULTIDISORDER || dp->desync_mode2==DESYNC_MULTISPLIT || dp->desync_mode2==DESYNC_MULTIDISORDER)
|
if (dp->desync_mode==DESYNC_MULTISPLIT || dp->desync_mode==DESYNC_MULTIDISORDER || dp->desync_mode2==DESYNC_MULTISPLIT || dp->desync_mode2==DESYNC_MULTIDISORDER)
|
||||||
@ -1224,13 +1371,8 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
else
|
else
|
||||||
seqovl_pos = 0;
|
seqovl_pos = 0;
|
||||||
|
|
||||||
// we do not need reasm buffer anymore
|
|
||||||
reasm_orig_cancel(ctrack);
|
|
||||||
rdata_payload=NULL;
|
|
||||||
|
|
||||||
uint32_t fooling_orig = FOOL_NONE;
|
uint32_t fooling_orig = FOOL_NONE;
|
||||||
bool bFake = false;
|
bool bFake = false;
|
||||||
pkt1_len = sizeof(pkt1);
|
|
||||||
switch(dp->desync_mode)
|
switch(dp->desync_mode)
|
||||||
{
|
{
|
||||||
case DESYNC_FAKE_KNOWN:
|
case DESYNC_FAKE_KNOWN:
|
||||||
@ -1242,28 +1384,69 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
}
|
}
|
||||||
case DESYNC_FAKE:
|
case DESYNC_FAKE:
|
||||||
if (reasm_offset) break;
|
if (reasm_offset) break;
|
||||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
|
||||||
ttl_fake,IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6),
|
|
||||||
dp->desync_fooling_mode,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
|
||||||
fake, fake_size, pkt1, &pkt1_len))
|
|
||||||
{
|
{
|
||||||
return verdict;
|
struct blob_item *fake_item;
|
||||||
|
uint8_t *fake_data;
|
||||||
|
uint8_t fake_data_buf[FAKE_MAX_TCP];
|
||||||
|
int n=0;
|
||||||
|
|
||||||
|
ip_id = IP4_IP_ID_FIX(dis->ip);
|
||||||
|
|
||||||
|
LIST_FOREACH(fake_item, fake, next)
|
||||||
|
{
|
||||||
|
n++;
|
||||||
|
switch(l7proto)
|
||||||
|
{
|
||||||
|
case TLS:
|
||||||
|
if ((fake_item->size <= sizeof(fake_data_buf)) &&
|
||||||
|
runtime_tls_mod(n,(struct fake_tls_mod_cache *)fake_item->extra,(struct fake_tls_mod *)fake_item->extra2, fake_item->data, fake_item->size, rdata_payload, rlen_payload, fake_data_buf))
|
||||||
|
{
|
||||||
|
fake_data = fake_data_buf;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
fake_data = fake_item->data;
|
||||||
|
}
|
||||||
|
pkt1_len = sizeof(pkt1);
|
||||||
|
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||||
|
ttl_fake,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||||
|
dp->desync_fooling_mode,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||||
|
fake_data, fake_item->size, pkt1, &pkt1_len))
|
||||||
|
{
|
||||||
|
reasm_orig_cancel(ctrack);
|
||||||
|
return verdict;
|
||||||
|
}
|
||||||
|
DLOG("sending fake[%d] : ", n);
|
||||||
|
hexdump_limited_dlog(fake_data,fake_item->size,PKTDATA_MAXDUMP); DLOG("\n");
|
||||||
|
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||||
|
{
|
||||||
|
reasm_orig_cancel(ctrack);
|
||||||
|
return verdict;
|
||||||
|
}
|
||||||
|
ip_id=IP4_IP_ID_NEXT(ip_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DLOG("sending fake : ");
|
|
||||||
hexdump_limited_dlog(fake,fake_size,PKTDATA_MAXDUMP); DLOG("\n");
|
|
||||||
bFake = true;
|
bFake = true;
|
||||||
break;
|
break;
|
||||||
case DESYNC_RST:
|
case DESYNC_RST:
|
||||||
case DESYNC_RSTACK:
|
case DESYNC_RSTACK:
|
||||||
if (reasm_offset) break;
|
if (reasm_offset) break;
|
||||||
|
pkt1_len = sizeof(pkt1);
|
||||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, TH_RST | (dp->desync_mode==DESYNC_RSTACK ? TH_ACK:0), dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, TH_RST | (dp->desync_mode==DESYNC_RSTACK ? TH_ACK:0), dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||||
ttl_fake,IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6),
|
ttl_fake,IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6),
|
||||||
dp->desync_fooling_mode,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
dp->desync_fooling_mode,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||||
NULL, 0, pkt1, &pkt1_len))
|
NULL, 0, pkt1, &pkt1_len))
|
||||||
{
|
{
|
||||||
|
reasm_orig_cancel(ctrack);
|
||||||
return verdict;
|
return verdict;
|
||||||
}
|
}
|
||||||
DLOG("sending fake RST/RSTACK\n");
|
DLOG("sending fake RST/RSTACK\n");
|
||||||
|
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||||
|
{
|
||||||
|
reasm_orig_cancel(ctrack);
|
||||||
|
return verdict;
|
||||||
|
}
|
||||||
bFake = true;
|
bFake = true;
|
||||||
break;
|
break;
|
||||||
case DESYNC_HOPBYHOP:
|
case DESYNC_HOPBYHOP:
|
||||||
@ -1274,8 +1457,12 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
(!split_pos && (dp->desync_mode2==DESYNC_FAKEDSPLIT || dp->desync_mode2==DESYNC_FAKEDDISORDER)) ||
|
(!split_pos && (dp->desync_mode2==DESYNC_FAKEDSPLIT || dp->desync_mode2==DESYNC_FAKEDDISORDER)) ||
|
||||||
(!multisplit_count && (dp->desync_mode2==DESYNC_MULTISPLIT || dp->desync_mode2==DESYNC_MULTIDISORDER))))
|
(!multisplit_count && (dp->desync_mode2==DESYNC_MULTISPLIT || dp->desync_mode2==DESYNC_MULTIDISORDER))))
|
||||||
{
|
{
|
||||||
|
reasm_orig_cancel(ctrack);
|
||||||
|
rdata_payload=NULL;
|
||||||
|
|
||||||
|
pkt1_len = sizeof(pkt1);
|
||||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||||
ttl_orig,IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6),
|
ttl_orig,0,0,IP6_FLOW(dis->ip6),
|
||||||
fooling_orig,0,0,
|
fooling_orig,0,0,
|
||||||
dis->data_payload, dis->len_payload, pkt1, &pkt1_len))
|
dis->data_payload, dis->len_payload, pkt1, &pkt1_len))
|
||||||
{
|
{
|
||||||
@ -1292,11 +1479,9 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bFake)
|
// we do not need reasm buffer anymore
|
||||||
{
|
reasm_orig_cancel(ctrack);
|
||||||
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
rdata_payload=NULL;
|
||||||
return verdict;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum dpi_desync_mode desync_mode = dp->desync_mode2==DESYNC_NONE ? dp->desync_mode : dp->desync_mode2;
|
enum dpi_desync_mode desync_mode = dp->desync_mode2==DESYNC_NONE ? dp->desync_mode : dp->desync_mode2;
|
||||||
switch(desync_mode)
|
switch(desync_mode)
|
||||||
@ -1317,7 +1502,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
// do seqovl only to the first packet
|
// do seqovl only to the first packet
|
||||||
// otherwise it's prone to race condition on server side
|
// otherwise it's prone to race condition on server side
|
||||||
// what happens first : server pushes socket buffer to process or another packet with seqovl arrives
|
// what happens first : server pushes socket buffer to process or another packet with seqovl arrives
|
||||||
seqovl = i==0 ? seqovl_pos : 0;
|
seqovl = (i==0 && reasm_offset==0) ? seqovl_pos : 0;
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
// only linux return error if MTU is exceeded
|
// only linux return error if MTU is exceeded
|
||||||
for(;;seqovl=0)
|
for(;;seqovl=0)
|
||||||
@ -1395,7 +1580,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
if (i==0)
|
if (i==0)
|
||||||
{
|
{
|
||||||
if (seqovl_pos>=from)
|
if (seqovl_pos>=from)
|
||||||
DLOG("seqovl>=split_pos (%u>=%zu). cancelling seqovl for part %d.\n",seqovl,from,i+2);
|
DLOG("seqovl>=split_pos (%zu>=%zu). cancelling seqovl for part %d.\n",seqovl,from,i+2);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
seqovl = seqovl_pos;
|
seqovl = seqovl_pos;
|
||||||
@ -1432,15 +1617,22 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
case DESYNC_FAKEDDISORDER:
|
case DESYNC_FAKEDDISORDER:
|
||||||
if (split_pos)
|
if (split_pos)
|
||||||
{
|
{
|
||||||
uint8_t fakeseg[DPI_DESYNC_MAX_FAKE_LEN+100], *seg;
|
uint8_t fakeseg[DPI_DESYNC_MAX_FAKE_LEN+100], fakeseg2[DPI_DESYNC_MAX_FAKE_LEN+100], pat[DPI_DESYNC_MAX_FAKE_LEN], *seg;
|
||||||
size_t seg_len;
|
size_t seg_len,fakeseg2_len;
|
||||||
unsigned int seqovl;
|
unsigned int seqovl;
|
||||||
|
|
||||||
|
if (dis->len_payload > sizeof(pat))
|
||||||
|
{
|
||||||
|
DLOG("packet is too large\n");
|
||||||
|
return verdict;
|
||||||
|
}
|
||||||
|
fill_pattern(pat,dis->len_payload,dp->fsplit_pattern,sizeof(dp->fsplit_pattern));
|
||||||
|
|
||||||
ip_id = IP4_IP_ID_FIX(dis->ip);
|
ip_id = IP4_IP_ID_FIX(dis->ip);
|
||||||
|
|
||||||
if (seqovl_pos>=split_pos)
|
if (seqovl_pos>=split_pos)
|
||||||
{
|
{
|
||||||
DLOG("seqovl>=split_pos (%u>=%zu). cancelling seqovl.\n",seqovl_pos,split_pos);
|
DLOG("seqovl>=split_pos (%zu>=%zu). cancelling seqovl.\n",seqovl_pos,split_pos);
|
||||||
seqovl = 0;
|
seqovl = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1463,6 +1655,19 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
seg = dis->data_payload+split_pos;
|
seg = dis->data_payload+split_pos;
|
||||||
seg_len = dis->len_payload-split_pos;
|
seg_len = dis->len_payload-split_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fakeseg2_len = sizeof(fakeseg2);
|
||||||
|
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(dis->tcp->th_seq,split_pos), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||||
|
ttl_fake,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||||
|
dp->desync_fooling_mode,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||||
|
pat+split_pos, dis->len_payload-split_pos, fakeseg2, &fakeseg2_len))
|
||||||
|
return verdict;
|
||||||
|
ip_id=IP4_IP_ID_PREV(ip_id);
|
||||||
|
DLOG("sending fake(1) 2nd out-of-order tcp segment %zu-%zu len=%zu : ",split_pos,dis->len_payload-1, dis->len_payload-split_pos);
|
||||||
|
hexdump_limited_dlog(pat+split_pos,dis->len_payload-split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
||||||
|
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg2, fakeseg2_len))
|
||||||
|
return verdict;
|
||||||
|
|
||||||
pkt1_len = sizeof(pkt1);
|
pkt1_len = sizeof(pkt1);
|
||||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(dis->tcp->th_seq , split_pos - seqovl), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(dis->tcp->th_seq , split_pos - seqovl), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||||
ttl_orig,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
ttl_orig,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||||
@ -1475,15 +1680,23 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||||
return verdict;
|
return verdict;
|
||||||
|
|
||||||
|
if (dis->ip) ((struct ip*)fakeseg2)->ip_id = ip_id;
|
||||||
|
ip_id=IP4_IP_ID_PREV(ip_id);
|
||||||
|
|
||||||
|
DLOG("sending fake(2) 2nd out-of-order tcp segment %zu-%zu len=%zu : ",split_pos,dis->len_payload-1, dis->len_payload-split_pos);
|
||||||
|
hexdump_limited_dlog(pat+split_pos,dis->len_payload-split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
||||||
|
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg2, fakeseg2_len))
|
||||||
|
return verdict;
|
||||||
|
|
||||||
seg_len = sizeof(fakeseg);
|
seg_len = sizeof(fakeseg);
|
||||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||||
ttl_fake,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
ttl_fake,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||||
dp->desync_fooling_mode,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
dp->desync_fooling_mode,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||||
zeropkt, split_pos, fakeseg, &seg_len))
|
pat, split_pos, fakeseg, &seg_len))
|
||||||
return verdict;
|
return verdict;
|
||||||
ip_id=IP4_IP_ID_PREV(ip_id);
|
ip_id=IP4_IP_ID_PREV(ip_id);
|
||||||
DLOG("sending fake(1) 1st out-of-order tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos);
|
DLOG("sending fake(1) 1st out-of-order tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos);
|
||||||
hexdump_limited_dlog(zeropkt,split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
hexdump_limited_dlog(pat,split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
||||||
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, seg_len))
|
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, seg_len))
|
||||||
return verdict;
|
return verdict;
|
||||||
|
|
||||||
@ -1501,7 +1714,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
|
|
||||||
if (dis->ip) ((struct ip*)fakeseg)->ip_id = ip_id;
|
if (dis->ip) ((struct ip*)fakeseg)->ip_id = ip_id;
|
||||||
DLOG("sending fake(2) 1st out-of-order tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos);
|
DLOG("sending fake(2) 1st out-of-order tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos);
|
||||||
hexdump_limited_dlog(zeropkt,split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
hexdump_limited_dlog(pat,split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
||||||
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, seg_len))
|
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, seg_len))
|
||||||
return verdict;
|
return verdict;
|
||||||
|
|
||||||
@ -1511,24 +1724,31 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
case DESYNC_FAKEDSPLIT:
|
case DESYNC_FAKEDSPLIT:
|
||||||
if (split_pos)
|
if (split_pos)
|
||||||
{
|
{
|
||||||
uint8_t fakeseg[DPI_DESYNC_MAX_FAKE_LEN+100],ovlseg[DPI_DESYNC_MAX_FAKE_LEN+100], *seg;
|
uint8_t fakeseg[DPI_DESYNC_MAX_FAKE_LEN+100],ovlseg[DPI_DESYNC_MAX_FAKE_LEN+100],pat[DPI_DESYNC_MAX_FAKE_LEN], *seg;
|
||||||
size_t fakeseg_len,seg_len;
|
size_t fakeseg_len,seg_len;
|
||||||
|
|
||||||
|
if (dis->len_payload > sizeof(pat))
|
||||||
|
{
|
||||||
|
DLOG("packet is too large\n");
|
||||||
|
return verdict;
|
||||||
|
}
|
||||||
|
fill_pattern(pat,dis->len_payload,dp->fsplit_pattern,sizeof(dp->fsplit_pattern));
|
||||||
|
|
||||||
ip_id = IP4_IP_ID_FIX(dis->ip);
|
ip_id = IP4_IP_ID_FIX(dis->ip);
|
||||||
|
|
||||||
fakeseg_len = sizeof(fakeseg);
|
fakeseg_len = sizeof(fakeseg);
|
||||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||||
ttl_fake,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
ttl_fake,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||||
dp->desync_fooling_mode,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
dp->desync_fooling_mode,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||||
zeropkt, split_pos, fakeseg, &fakeseg_len))
|
pat, split_pos, fakeseg, &fakeseg_len))
|
||||||
return verdict;
|
return verdict;
|
||||||
ip_id=IP4_IP_ID_NEXT(ip_id);
|
ip_id=IP4_IP_ID_NEXT(ip_id);
|
||||||
DLOG("sending fake(1) 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos);
|
DLOG("sending fake(1) 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos);
|
||||||
hexdump_limited_dlog(zeropkt,split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
hexdump_limited_dlog(pat,split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
||||||
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len))
|
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len))
|
||||||
return verdict;
|
return verdict;
|
||||||
|
|
||||||
unsigned int seqovl = seqovl_pos;
|
unsigned int seqovl = reasm_offset ? 0 : seqovl_pos;
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
// only linux return error if MTU is exceeded
|
// only linux return error if MTU is exceeded
|
||||||
for(;;seqovl=0)
|
for(;;seqovl=0)
|
||||||
@ -1579,7 +1799,19 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
if (dis->ip) ((struct ip*)fakeseg)->ip_id = ip_id;
|
if (dis->ip) ((struct ip*)fakeseg)->ip_id = ip_id;
|
||||||
ip_id=IP4_IP_ID_NEXT(ip_id);
|
ip_id=IP4_IP_ID_NEXT(ip_id);
|
||||||
DLOG("sending fake(2) 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos);
|
DLOG("sending fake(2) 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos);
|
||||||
hexdump_limited_dlog(zeropkt,split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
hexdump_limited_dlog(pat,split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
||||||
|
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len))
|
||||||
|
return verdict;
|
||||||
|
|
||||||
|
fakeseg_len = sizeof(fakeseg);
|
||||||
|
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(dis->tcp->th_seq,split_pos), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||||
|
ttl_fake,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||||
|
dp->desync_fooling_mode,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||||
|
pat+split_pos, dis->len_payload-split_pos, fakeseg, &fakeseg_len))
|
||||||
|
return verdict;
|
||||||
|
ip_id=IP4_IP_ID_NEXT(ip_id);
|
||||||
|
DLOG("sending fake(1) 2nd tcp segment %zu-%zu len=%zu : ",split_pos,dis->len_payload-1, dis->len_payload-split_pos);
|
||||||
|
hexdump_limited_dlog(pat+split_pos,dis->len_payload-split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
||||||
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len))
|
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len))
|
||||||
return verdict;
|
return verdict;
|
||||||
|
|
||||||
@ -1589,11 +1821,19 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
fooling_orig,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
fooling_orig,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||||
dis->data_payload+split_pos, dis->len_payload-split_pos, pkt1, &pkt1_len))
|
dis->data_payload+split_pos, dis->len_payload-split_pos, pkt1, &pkt1_len))
|
||||||
return verdict;
|
return verdict;
|
||||||
|
ip_id=IP4_IP_ID_NEXT(ip_id);
|
||||||
DLOG("sending 2nd tcp segment %zu-%zu len=%zu : ",split_pos,dis->len_payload-1, dis->len_payload-split_pos);
|
DLOG("sending 2nd tcp segment %zu-%zu len=%zu : ",split_pos,dis->len_payload-1, dis->len_payload-split_pos);
|
||||||
hexdump_limited_dlog(dis->data_payload+split_pos,dis->len_payload-split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
hexdump_limited_dlog(dis->data_payload+split_pos,dis->len_payload-split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
||||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||||
return verdict;
|
return verdict;
|
||||||
|
|
||||||
|
if (dis->ip) ((struct ip*)fakeseg)->ip_id = ip_id;
|
||||||
|
|
||||||
|
DLOG("sending fake(2) 2nd tcp segment %zu-%zu len=%zu : ",split_pos,dis->len_payload-1, dis->len_payload-split_pos);
|
||||||
|
hexdump_limited_dlog(pat+split_pos,dis->len_payload-split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
||||||
|
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len))
|
||||||
|
return verdict;
|
||||||
|
|
||||||
return VERDICT_DROP;
|
return VERDICT_DROP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1771,8 +2011,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
|
|
||||||
if (dis->len_payload)
|
if (dis->len_payload)
|
||||||
{
|
{
|
||||||
const uint8_t *fake;
|
struct blob_collection_head *fake;
|
||||||
size_t fake_size;
|
|
||||||
char host[256];
|
char host[256];
|
||||||
bool bHaveHost=false;
|
bool bHaveHost=false;
|
||||||
uint16_t ip_id;
|
uint16_t ip_id;
|
||||||
@ -1813,29 +2052,84 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
return verdict; // cannot be first packet
|
return verdict; // cannot be first packet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uint8_t defrag[UDP_MAX_REASM];
|
||||||
uint8_t defrag[16384];
|
|
||||||
size_t hello_offset, hello_len, defrag_len = sizeof(defrag);
|
size_t hello_offset, hello_len, defrag_len = sizeof(defrag);
|
||||||
if (QUICDefragCrypto(pclean,clean_len,defrag,&defrag_len))
|
bool bFull;
|
||||||
|
if (QUICDefragCrypto(pclean,clean_len,defrag,&defrag_len,&bFull))
|
||||||
{
|
{
|
||||||
bool bIsHello = IsQUICCryptoHello(defrag, defrag_len, &hello_offset, &hello_len);
|
if (bFull)
|
||||||
bool bReqFull = bIsHello ? IsTLSHandshakeFull(defrag+hello_offset,hello_len) : false;
|
|
||||||
|
|
||||||
DLOG(bIsHello ? bReqFull ? "packet contains full TLS ClientHello\n" : "packet contains partial TLS ClientHello\n" : "packet does not contain TLS ClientHello\n");
|
|
||||||
|
|
||||||
if (ctrack)
|
|
||||||
{
|
{
|
||||||
if (bIsHello && !bReqFull && ReasmIsEmpty(&ctrack->reasm_orig))
|
DLOG("QUIC initial contains CRYPTO with full fragment coverage\n");
|
||||||
|
|
||||||
|
bool bIsHello = IsQUICCryptoHello(defrag, defrag_len, &hello_offset, &hello_len);
|
||||||
|
bool bReqFull = bIsHello ? IsTLSHandshakeFull(defrag+hello_offset,hello_len) : false;
|
||||||
|
|
||||||
|
DLOG(bIsHello ? bReqFull ? "packet contains full TLS ClientHello\n" : "packet contains partial TLS ClientHello\n" : "packet does not contain TLS ClientHello\n");
|
||||||
|
|
||||||
|
if (bReqFull) TLSDebugHandshake(defrag+hello_offset,hello_len);
|
||||||
|
|
||||||
|
if (ctrack)
|
||||||
{
|
{
|
||||||
// preallocate max buffer to avoid reallocs that cause memory copy
|
if (bIsHello && !bReqFull && ReasmIsEmpty(&ctrack->reasm_orig))
|
||||||
if (!reasm_orig_start(ctrack,IPPROTO_UDP,16384,16384,clean,clean_len))
|
{
|
||||||
|
// preallocate max buffer to avoid reallocs that cause memory copy
|
||||||
|
if (!reasm_orig_start(ctrack,IPPROTO_UDP,UDP_MAX_REASM,UDP_MAX_REASM,clean,clean_len))
|
||||||
|
{
|
||||||
|
reasm_orig_cancel(ctrack);
|
||||||
|
return verdict;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ReasmIsEmpty(&ctrack->reasm_orig))
|
||||||
|
{
|
||||||
|
verdict_udp_csum_fix(verdict, dis->udp, dis->transport_len, dis->ip, dis->ip6);
|
||||||
|
if (rawpacket_queue(&ctrack->delayed, &dst, desync_fwmark, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload))
|
||||||
|
{
|
||||||
|
DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ctrack->delayed));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DLOG_ERR("rawpacket_queue failed !\n");
|
||||||
|
reasm_orig_cancel(ctrack);
|
||||||
|
return verdict;
|
||||||
|
}
|
||||||
|
if (bReqFull)
|
||||||
|
{
|
||||||
|
replay_queue(&ctrack->delayed);
|
||||||
|
reasm_orig_fin(ctrack);
|
||||||
|
}
|
||||||
|
return ct_new_postnat_fix_udp(ctrack, dis->ip, dis->ip6, dis->udp, &dis->len_pkt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bIsHello)
|
||||||
|
{
|
||||||
|
bHaveHost = TLSHelloExtractHostFromHandshake(defrag + hello_offset, hello_len, host, sizeof(host), TLS_PARTIALS_ENABLE);
|
||||||
|
if (!bHaveHost && dp->desync_skip_nosni)
|
||||||
{
|
{
|
||||||
reasm_orig_cancel(ctrack);
|
reasm_orig_cancel(ctrack);
|
||||||
|
DLOG("not applying tampering to QUIC ClientHello without hostname in the SNI\n");
|
||||||
return verdict;
|
return verdict;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!ReasmIsEmpty(&ctrack->reasm_orig))
|
else
|
||||||
{
|
{
|
||||||
|
if (!quic_reasm_cancel(ctrack,"QUIC initial without ClientHello")) return verdict;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DLOG("QUIC initial contains CRYPTO with partial fragment coverage\n");
|
||||||
|
if (ctrack)
|
||||||
|
{
|
||||||
|
if (ReasmIsEmpty(&ctrack->reasm_orig))
|
||||||
|
{
|
||||||
|
// preallocate max buffer to avoid reallocs that cause memory copy
|
||||||
|
if (!reasm_orig_start(ctrack,IPPROTO_UDP,UDP_MAX_REASM,UDP_MAX_REASM,clean,clean_len))
|
||||||
|
{
|
||||||
|
reasm_orig_cancel(ctrack);
|
||||||
|
return verdict;
|
||||||
|
}
|
||||||
|
}
|
||||||
verdict_udp_csum_fix(verdict, dis->udp, dis->transport_len, dis->ip, dis->ip6);
|
verdict_udp_csum_fix(verdict, dis->udp, dis->transport_len, dis->ip, dis->ip6);
|
||||||
if (rawpacket_queue(&ctrack->delayed, &dst, desync_fwmark, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload))
|
if (rawpacket_queue(&ctrack->delayed, &dst, desync_fwmark, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload))
|
||||||
{
|
{
|
||||||
@ -1847,28 +2141,9 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
reasm_orig_cancel(ctrack);
|
reasm_orig_cancel(ctrack);
|
||||||
return verdict;
|
return verdict;
|
||||||
}
|
}
|
||||||
if (bReqFull)
|
|
||||||
{
|
|
||||||
replay_queue(&ctrack->delayed);
|
|
||||||
reasm_orig_fin(ctrack);
|
|
||||||
}
|
|
||||||
return ct_new_postnat_fix_udp(ctrack, dis->ip, dis->ip6, dis->udp, &dis->len_pkt);
|
return ct_new_postnat_fix_udp(ctrack, dis->ip, dis->ip6, dis->udp, &dis->len_pkt);
|
||||||
}
|
}
|
||||||
}
|
if (!quic_reasm_cancel(ctrack,"QUIC initial fragmented CRYPTO")) return verdict;
|
||||||
|
|
||||||
if (bIsHello)
|
|
||||||
{
|
|
||||||
bHaveHost = TLSHelloExtractHostFromHandshake(defrag + hello_offset, hello_len, host, sizeof(host), TLS_PARTIALS_ENABLE);
|
|
||||||
if (!bHaveHost && dp->desync_skip_nosni)
|
|
||||||
{
|
|
||||||
reasm_orig_cancel(ctrack);
|
|
||||||
DLOG("not applying tampering to QUIC ClientHello without hostname in the SNI\n");
|
|
||||||
return verdict;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!quic_reasm_cancel(ctrack,"QUIC initial without ClientHello")) return verdict;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1887,7 +2162,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
{
|
{
|
||||||
// received payload without host. it means we are out of the request retransmission phase. stop counter
|
// received payload without host. it means we are out of the request retransmission phase. stop counter
|
||||||
ctrack_stop_retrans_counter(ctrack);
|
ctrack_stop_retrans_counter(ctrack);
|
||||||
|
|
||||||
reasm_orig_cancel(ctrack);
|
reasm_orig_cancel(ctrack);
|
||||||
|
|
||||||
if (IsWireguardHandshakeInitiation(dis->data_payload,dis->len_payload))
|
if (IsWireguardHandshakeInitiation(dis->data_payload,dis->len_payload))
|
||||||
@ -1902,6 +2177,18 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
l7proto = DHT;
|
l7proto = DHT;
|
||||||
if (ctrack && ctrack->l7proto==UNKNOWN) ctrack->l7proto = l7proto;
|
if (ctrack && ctrack->l7proto==UNKNOWN) ctrack->l7proto = l7proto;
|
||||||
}
|
}
|
||||||
|
else if (IsDiscordIpDiscoveryRequest(dis->data_payload,dis->len_payload))
|
||||||
|
{
|
||||||
|
DLOG("packet contains discord voice IP discovery\n");
|
||||||
|
l7proto = DISCORD;
|
||||||
|
if (ctrack && ctrack->l7proto==UNKNOWN) ctrack->l7proto = l7proto;
|
||||||
|
}
|
||||||
|
else if (IsStunMessage(dis->data_payload,dis->len_payload))
|
||||||
|
{
|
||||||
|
DLOG("packet contains STUN message\n");
|
||||||
|
l7proto = STUN;
|
||||||
|
if (ctrack && ctrack->l7proto==UNKNOWN) ctrack->l7proto = l7proto;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!dp->desync_any_proto)
|
if (!dp->desync_any_proto)
|
||||||
@ -2006,20 +2293,22 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
switch(l7proto)
|
switch(l7proto)
|
||||||
{
|
{
|
||||||
case QUIC:
|
case QUIC:
|
||||||
fake = dp->fake_quic;
|
fake = &dp->fake_quic;
|
||||||
fake_size = dp->fake_quic_size;
|
|
||||||
break;
|
break;
|
||||||
case WIREGUARD:
|
case WIREGUARD:
|
||||||
fake = dp->fake_wg;
|
fake = &dp->fake_wg;
|
||||||
fake_size = dp->fake_wg_size;
|
|
||||||
break;
|
break;
|
||||||
case DHT:
|
case DHT:
|
||||||
fake = dp->fake_dht;
|
fake = &dp->fake_dht;
|
||||||
fake_size = dp->fake_dht_size;
|
break;
|
||||||
|
case DISCORD:
|
||||||
|
fake = &dp->fake_discord;
|
||||||
|
break;
|
||||||
|
case STUN:
|
||||||
|
fake = &dp->fake_stun;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fake = dp->fake_unknown_udp;
|
fake = &dp->fake_unknown_udp;
|
||||||
fake_size = dp->fake_unknown_udp_size;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2036,7 +2325,6 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool bFake = false;
|
bool bFake = false;
|
||||||
pkt1_len = sizeof(pkt1);
|
|
||||||
switch(dp->desync_mode)
|
switch(dp->desync_mode)
|
||||||
{
|
{
|
||||||
case DESYNC_FAKE_KNOWN:
|
case DESYNC_FAKE_KNOWN:
|
||||||
@ -2046,12 +2334,30 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DESYNC_FAKE:
|
case DESYNC_FAKE:
|
||||||
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, ttl_fake, IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6), dp->desync_fooling_mode, NULL, 0, 0, fake, fake_size, pkt1, &pkt1_len))
|
{
|
||||||
return verdict;
|
struct blob_item *fake_item;
|
||||||
DLOG("sending fake : ");
|
int n=0;
|
||||||
hexdump_limited_dlog(fake,fake_size,PKTDATA_MAXDUMP); DLOG("\n");
|
|
||||||
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
ip_id = IP4_IP_ID_FIX(dis->ip);
|
||||||
return verdict;
|
|
||||||
|
LIST_FOREACH(fake_item, fake, next)
|
||||||
|
{
|
||||||
|
n++;
|
||||||
|
pkt1_len = sizeof(pkt1);
|
||||||
|
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst,
|
||||||
|
ttl_fake, IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||||
|
dp->desync_fooling_mode, NULL, 0, 0,
|
||||||
|
fake_item->data, fake_item->size, pkt1, &pkt1_len))
|
||||||
|
{
|
||||||
|
return verdict;
|
||||||
|
}
|
||||||
|
DLOG("sending fake[%d] : ", n);
|
||||||
|
hexdump_limited_dlog(fake_item->data,fake_item->size,PKTDATA_MAXDUMP); DLOG("\n");
|
||||||
|
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||||
|
return verdict;
|
||||||
|
ip_id=IP4_IP_ID_NEXT(ip_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
bFake = true;
|
bFake = true;
|
||||||
break;
|
break;
|
||||||
case DESYNC_HOPBYHOP:
|
case DESYNC_HOPBYHOP:
|
||||||
@ -2060,9 +2366,9 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
fooling_orig = (dp->desync_mode==DESYNC_HOPBYHOP) ? FOOL_HOPBYHOP : (dp->desync_mode==DESYNC_DESTOPT) ? FOOL_DESTOPT : FOOL_IPFRAG1;
|
fooling_orig = (dp->desync_mode==DESYNC_HOPBYHOP) ? FOOL_HOPBYHOP : (dp->desync_mode==DESYNC_DESTOPT) ? FOOL_DESTOPT : FOOL_IPFRAG1;
|
||||||
if (dis->ip6 && (dp->desync_mode2==DESYNC_NONE || !desync_valid_second_stage_udp(dp->desync_mode2)))
|
if (dis->ip6 && (dp->desync_mode2==DESYNC_NONE || !desync_valid_second_stage_udp(dp->desync_mode2)))
|
||||||
{
|
{
|
||||||
|
pkt1_len = sizeof(pkt1);
|
||||||
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst,
|
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst,
|
||||||
ttl_orig,IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6),
|
ttl_orig,0,0,IP6_FLOW(dis->ip6),fooling_orig,NULL,0,0,
|
||||||
fooling_orig,NULL,0,0,
|
|
||||||
dis->data_payload, dis->len_payload, pkt1, &pkt1_len))
|
dis->data_payload, dis->len_payload, pkt1, &pkt1_len))
|
||||||
{
|
{
|
||||||
return verdict;
|
return verdict;
|
||||||
|
@ -41,7 +41,7 @@ enum dpi_desync_mode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern const char *fake_http_request_default;
|
extern const char *fake_http_request_default;
|
||||||
extern const uint8_t fake_tls_clienthello_default[648];
|
extern const uint8_t fake_tls_clienthello_default[680];
|
||||||
void randomize_default_tls_payload(uint8_t *p);
|
void randomize_default_tls_payload(uint8_t *p);
|
||||||
|
|
||||||
enum dpi_desync_mode desync_mode_from_string(const char *s);
|
enum dpi_desync_mode desync_mode_from_string(const char *s);
|
||||||
@ -52,5 +52,4 @@ bool desync_valid_second_stage(enum dpi_desync_mode mode);
|
|||||||
bool desync_valid_second_stage_tcp(enum dpi_desync_mode mode);
|
bool desync_valid_second_stage_tcp(enum dpi_desync_mode mode);
|
||||||
bool desync_valid_second_stage_udp(enum dpi_desync_mode mode);
|
bool desync_valid_second_stage_udp(enum dpi_desync_mode mode);
|
||||||
|
|
||||||
void desync_init(void);
|
|
||||||
uint8_t dpi_desync_packet(uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt);
|
uint8_t dpi_desync_packet(uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt);
|
||||||
|
@ -65,11 +65,8 @@ int z_readfile(FILE *F, char **buf, size_t *size)
|
|||||||
|
|
||||||
zerr:
|
zerr:
|
||||||
inflateEnd(&zs);
|
inflateEnd(&zs);
|
||||||
if (*buf)
|
free(*buf);
|
||||||
{
|
*buf = NULL;
|
||||||
free(*buf);
|
|
||||||
*buf = NULL;
|
|
||||||
}
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
int unique_size_t(size_t *pu, int ct)
|
int unique_size_t(size_t *pu, int ct)
|
||||||
{
|
{
|
||||||
@ -300,6 +301,29 @@ time_t file_mod_time(const char *filename)
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
return stat(filename,&st)==-1 ? 0 : st.st_mtime;
|
return stat(filename,&st)==-1 ? 0 : st.st_mtime;
|
||||||
}
|
}
|
||||||
|
bool file_mod_signature(const char *filename, file_mod_sig *ms)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
if (stat(filename,&st)==-1)
|
||||||
|
{
|
||||||
|
FILE_MOD_RESET(ms);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ms->mod_time=st.st_mtime;
|
||||||
|
ms->size=st.st_size;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool file_open_test(const char *filename, int flags)
|
||||||
|
{
|
||||||
|
int fd = open(filename,flags);
|
||||||
|
if (fd>=0)
|
||||||
|
{
|
||||||
|
close(fd);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool pf_in_range(uint16_t port, const port_filter *pf)
|
bool pf_in_range(uint16_t port, const port_filter *pf)
|
||||||
{
|
{
|
||||||
@ -367,6 +391,12 @@ void fill_random_az09(uint8_t *p,size_t sz)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_console_io_buffering(void)
|
||||||
|
{
|
||||||
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
|
setvbuf(stderr, NULL, _IOLBF, 0);
|
||||||
|
}
|
||||||
|
|
||||||
bool set_env_exedir(const char *argv0)
|
bool set_env_exedir(const char *argv0)
|
||||||
{
|
{
|
||||||
char *s,*d;
|
char *s,*d;
|
||||||
|
@ -51,6 +51,14 @@ static inline void phton16(uint8_t *p, uint16_t v) {
|
|||||||
p[0] = (uint8_t)(v >> 8);
|
p[0] = (uint8_t)(v >> 8);
|
||||||
p[1] = v & 0xFF;
|
p[1] = v & 0xFF;
|
||||||
}
|
}
|
||||||
|
static inline uint32_t pntoh24(const uint8_t *p) {
|
||||||
|
return ((uint32_t)p[0] << 16) | ((uint32_t)p[1] << 8) | (uint32_t)p[2];
|
||||||
|
}
|
||||||
|
static inline void phton24(uint8_t *p, uint32_t v) {
|
||||||
|
p[0] = (uint8_t)(v>>16);
|
||||||
|
p[1] = (uint8_t)(v>>8);
|
||||||
|
p[2] = (uint8_t)v;
|
||||||
|
}
|
||||||
static inline uint32_t pntoh32(const uint8_t *p) {
|
static inline uint32_t pntoh32(const uint8_t *p) {
|
||||||
return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | (uint32_t)p[3];
|
return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | (uint32_t)p[3];
|
||||||
}
|
}
|
||||||
@ -60,7 +68,16 @@ void fill_pattern(uint8_t *buf,size_t bufsize,const void *pattern,size_t patsize
|
|||||||
|
|
||||||
int fprint_localtime(FILE *F);
|
int fprint_localtime(FILE *F);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
time_t mod_time;
|
||||||
|
off_t size;
|
||||||
|
} file_mod_sig;
|
||||||
|
#define FILE_MOD_COMPARE(ms1,ms2) (((ms1)->mod_time==(ms2)->mod_time) && ((ms1)->size==(ms2)->size))
|
||||||
|
#define FILE_MOD_RESET(ms) memset(ms,0,sizeof(file_mod_sig))
|
||||||
|
bool file_mod_signature(const char *filename, file_mod_sig *ms);
|
||||||
time_t file_mod_time(const char *filename);
|
time_t file_mod_time(const char *filename);
|
||||||
|
bool file_open_test(const char *filename, int flags);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -75,6 +92,7 @@ void fill_random_bytes(uint8_t *p,size_t sz);
|
|||||||
void fill_random_az(uint8_t *p,size_t sz);
|
void fill_random_az(uint8_t *p,size_t sz);
|
||||||
void fill_random_az09(uint8_t *p,size_t sz);
|
void fill_random_az09(uint8_t *p,size_t sz);
|
||||||
|
|
||||||
|
void set_console_io_buffering(void);
|
||||||
bool set_env_exedir(const char *argv0);
|
bool set_env_exedir(const char *argv0);
|
||||||
|
|
||||||
|
|
||||||
|
127
nfq/hostlist.c
127
nfq/hostlist.c
@ -4,7 +4,7 @@
|
|||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|
||||||
// inplace tolower() and add to pool
|
// inplace tolower() and add to pool
|
||||||
static bool addpool(strpool **hostlist, char **s, const char *end, int *ct)
|
static bool addpool(hostlist_pool **hostlist, char **s, const char *end, int *ct)
|
||||||
{
|
{
|
||||||
char *p=*s;
|
char *p=*s;
|
||||||
|
|
||||||
@ -17,14 +17,20 @@ static bool addpool(strpool **hostlist, char **s, const char *end, int *ct)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// advance until eol lowering all chars
|
// advance until eol lowering all chars
|
||||||
for (; p<end && *p && *p!='\r' && *p != '\n'; p++) *p=tolower(*p);
|
uint32_t flags = 0;
|
||||||
if (!StrPoolAddStrLen(hostlist, *s, p-*s))
|
if (*p=='^')
|
||||||
{
|
{
|
||||||
StrPoolDestroy(hostlist);
|
p = ++(*s);
|
||||||
|
flags |= HOSTLIST_POOL_FLAG_STRICT_MATCH;
|
||||||
|
}
|
||||||
|
for (; p<end && *p && *p!='\r' && *p != '\n'; p++) *p=tolower(*p);
|
||||||
|
if (!HostlistPoolAddStrLen(hostlist, *s, p-*s, flags))
|
||||||
|
{
|
||||||
|
HostlistPoolDestroy(hostlist);
|
||||||
*hostlist = NULL;
|
*hostlist = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
(*ct)++;
|
if (ct) (*ct)++;
|
||||||
}
|
}
|
||||||
// advance to the next line
|
// advance to the next line
|
||||||
for (; p<end && (!*p || *p=='\r' || *p=='\n') ; p++);
|
for (; p<end && (!*p || *p=='\r' || *p=='\n') ; p++);
|
||||||
@ -32,7 +38,12 @@ static bool addpool(strpool **hostlist, char **s, const char *end, int *ct)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppendHostList(strpool **hostlist, const char *filename)
|
bool AppendHostlistItem(hostlist_pool **hostlist, char *s)
|
||||||
|
{
|
||||||
|
return addpool(hostlist,&s,s+strlen(s),NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppendHostList(hostlist_pool **hostlist, const char *filename)
|
||||||
{
|
{
|
||||||
char *p, *e, s[256], *zbuf;
|
char *p, *e, s[256], *zbuf;
|
||||||
size_t zsize;
|
size_t zsize;
|
||||||
@ -98,21 +109,25 @@ bool AppendHostList(strpool **hostlist, const char *filename)
|
|||||||
|
|
||||||
static bool LoadHostList(struct hostlist_file *hfile)
|
static bool LoadHostList(struct hostlist_file *hfile)
|
||||||
{
|
{
|
||||||
time_t t = file_mod_time(hfile->filename);
|
if (hfile->filename)
|
||||||
if (!t)
|
|
||||||
{
|
{
|
||||||
// stat() error
|
file_mod_sig fsig;
|
||||||
DLOG_ERR("cannot access hostlist file '%s'. in-memory content remains unchanged.\n",hfile->filename);
|
if (!file_mod_signature(hfile->filename, &fsig))
|
||||||
return true;
|
{
|
||||||
|
// stat() error
|
||||||
|
DLOG_PERROR("file_mod_signature");
|
||||||
|
DLOG_ERR("cannot access hostlist file '%s'. in-memory content remains unchanged.\n",hfile->filename);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (FILE_MOD_COMPARE(&hfile->mod_sig,&fsig)) return true; // up to date
|
||||||
|
HostlistPoolDestroy(&hfile->hostlist);
|
||||||
|
if (!AppendHostList(&hfile->hostlist, hfile->filename))
|
||||||
|
{
|
||||||
|
HostlistPoolDestroy(&hfile->hostlist);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
hfile->mod_sig=fsig;
|
||||||
}
|
}
|
||||||
if (t==hfile->mod_time) return true; // up to date
|
|
||||||
StrPoolDestroy(&hfile->hostlist);
|
|
||||||
if (!AppendHostList(&hfile->hostlist, hfile->filename))
|
|
||||||
{
|
|
||||||
StrPoolDestroy(&hfile->hostlist);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
hfile->mod_time=t;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
static bool LoadHostLists(struct hostlist_files_head *list)
|
static bool LoadHostLists(struct hostlist_files_head *list)
|
||||||
@ -129,10 +144,10 @@ static bool LoadHostLists(struct hostlist_files_head *list)
|
|||||||
return bres;
|
return bres;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NonEmptyHostlist(strpool **hostlist)
|
bool NonEmptyHostlist(hostlist_pool **hostlist)
|
||||||
{
|
{
|
||||||
// add impossible hostname if the list is empty
|
// add impossible hostname if the list is empty
|
||||||
return *hostlist ? true : StrPoolAddStrLen(hostlist, "@&()", 4);
|
return *hostlist ? true : HostlistPoolAddStrLen(hostlist, "@&()", 4, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MakeAutolistsNonEmpty()
|
static void MakeAutolistsNonEmpty()
|
||||||
@ -155,19 +170,34 @@ bool LoadAllHostLists()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool SearchHostList(strpool *hostlist, const char *host)
|
static bool SearchHostList(hostlist_pool *hostlist, const char *host)
|
||||||
{
|
{
|
||||||
if (hostlist)
|
if (hostlist)
|
||||||
{
|
{
|
||||||
const char *p = host;
|
const char *p = host;
|
||||||
bool bInHostList;
|
const struct hostlist_pool *hp;
|
||||||
|
bool bHostFull=true;
|
||||||
while (p)
|
while (p)
|
||||||
{
|
{
|
||||||
bInHostList = StrPoolCheckStr(hostlist, p);
|
DLOG("hostlist check for %s : ", p);
|
||||||
DLOG("hostlist check for %s : %s\n", p, bInHostList ? "positive" : "negative");
|
hp = HostlistPoolGetStr(hostlist, p);
|
||||||
if (bInHostList) return true;
|
if (hp)
|
||||||
|
{
|
||||||
|
if ((hp->flags & HOSTLIST_POOL_FLAG_STRICT_MATCH) && !bHostFull)
|
||||||
|
{
|
||||||
|
DLOG("negative : strict_mismatch : %s != %s\n", p, host);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DLOG("positive\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DLOG("negative\n");
|
||||||
p = strchr(p, '.');
|
p = strchr(p, '.');
|
||||||
if (p) p++;
|
if (p) p++;
|
||||||
|
bHostFull = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -202,7 +232,7 @@ static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, con
|
|||||||
|
|
||||||
LIST_FOREACH(item, hostlists_exclude, next)
|
LIST_FOREACH(item, hostlists_exclude, next)
|
||||||
{
|
{
|
||||||
DLOG("[%s] exclude ", item->hfile->filename);
|
DLOG("[%s] exclude ", item->hfile->filename ? item->hfile->filename : "fixed");
|
||||||
if (SearchHostList(item->hfile->hostlist, host))
|
if (SearchHostList(item->hfile->hostlist, host))
|
||||||
{
|
{
|
||||||
if (excluded) *excluded = true;
|
if (excluded) *excluded = true;
|
||||||
@ -214,7 +244,7 @@ static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, con
|
|||||||
{
|
{
|
||||||
LIST_FOREACH(item, hostlists, next)
|
LIST_FOREACH(item, hostlists, next)
|
||||||
{
|
{
|
||||||
DLOG("[%s] include ", item->hfile->filename);
|
DLOG("[%s] include ", item->hfile->filename ? item->hfile->filename : "fixed");
|
||||||
if (SearchHostList(item->hfile->hostlist, host))
|
if (SearchHostList(item->hfile->hostlist, host))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -235,17 +265,29 @@ bool HostlistCheck(const struct desync_profile *dp, const char *host, bool *excl
|
|||||||
static struct hostlist_file *RegisterHostlist_(struct hostlist_files_head *hostlists, struct hostlist_collection_head *hl_collection, const char *filename)
|
static struct hostlist_file *RegisterHostlist_(struct hostlist_files_head *hostlists, struct hostlist_collection_head *hl_collection, const char *filename)
|
||||||
{
|
{
|
||||||
struct hostlist_file *hfile;
|
struct hostlist_file *hfile;
|
||||||
if (!(hfile=hostlist_files_search(hostlists, filename)))
|
|
||||||
if (!(hfile=hostlist_files_add(hostlists, filename)))
|
if (filename)
|
||||||
|
{
|
||||||
|
if (!(hfile=hostlist_files_search(hostlists, filename)))
|
||||||
|
if (!(hfile=hostlist_files_add(hostlists, filename)))
|
||||||
|
return NULL;
|
||||||
|
if (!hostlist_collection_search(hl_collection, filename))
|
||||||
|
if (!hostlist_collection_add(hl_collection, hfile))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(hfile=hostlist_files_add(hostlists, NULL)))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!hostlist_collection_search(hl_collection, filename))
|
|
||||||
if (!hostlist_collection_add(hl_collection, hfile))
|
if (!hostlist_collection_add(hl_collection, hfile))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return hfile;
|
return hfile;
|
||||||
}
|
}
|
||||||
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename)
|
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename)
|
||||||
{
|
{
|
||||||
if (!file_mod_time(filename))
|
if (filename && !file_mod_time(filename))
|
||||||
{
|
{
|
||||||
DLOG_ERR("cannot access hostlist file '%s'\n",filename);
|
DLOG_ERR("cannot access hostlist file '%s'\n",filename);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -265,15 +307,30 @@ void HostlistsDebug()
|
|||||||
struct hostlist_item *hl_item;
|
struct hostlist_item *hl_item;
|
||||||
|
|
||||||
LIST_FOREACH(hfile, ¶ms.hostlists, next)
|
LIST_FOREACH(hfile, ¶ms.hostlists, next)
|
||||||
DLOG("hostlist file %s%s\n",hfile->filename,hfile->hostlist ? "" : " (empty)");
|
{
|
||||||
|
if (hfile->filename)
|
||||||
|
DLOG("hostlist file %s%s\n",hfile->filename,hfile->hostlist ? "" : " (empty)");
|
||||||
|
else
|
||||||
|
DLOG("hostlist fixed%s\n",hfile->hostlist ? "" : " (empty)");
|
||||||
|
}
|
||||||
|
|
||||||
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
||||||
{
|
{
|
||||||
LIST_FOREACH(hl_item, &dpl->dp.hl_collection, next)
|
LIST_FOREACH(hl_item, &dpl->dp.hl_collection, next)
|
||||||
if (hl_item->hfile!=dpl->dp.hostlist_auto)
|
if (hl_item->hfile!=dpl->dp.hostlist_auto)
|
||||||
DLOG("profile %d include hostlist %s%s\n",dpl->dp.n, hl_item->hfile->filename,hl_item->hfile->hostlist ? "" : " (empty)");
|
{
|
||||||
|
if (hl_item->hfile->filename)
|
||||||
|
DLOG("profile %d include hostlist %s%s\n",dpl->dp.n, hl_item->hfile->filename,hl_item->hfile->hostlist ? "" : " (empty)");
|
||||||
|
else
|
||||||
|
DLOG("profile %d include fixed hostlist%s\n",dpl->dp.n, hl_item->hfile->hostlist ? "" : " (empty)");
|
||||||
|
}
|
||||||
LIST_FOREACH(hl_item, &dpl->dp.hl_collection_exclude, next)
|
LIST_FOREACH(hl_item, &dpl->dp.hl_collection_exclude, next)
|
||||||
DLOG("profile %d exclude hostlist %s%s\n",dpl->dp.n,hl_item->hfile->filename,hl_item->hfile->hostlist ? "" : " (empty)");
|
{
|
||||||
|
if (hl_item->hfile->filename)
|
||||||
|
DLOG("profile %d exclude hostlist %s%s\n",dpl->dp.n,hl_item->hfile->filename,hl_item->hfile->hostlist ? "" : " (empty)");
|
||||||
|
else
|
||||||
|
DLOG("profile %d exclude fixed hostlist%s\n",dpl->dp.n,hl_item->hfile->hostlist ? "" : " (empty)");
|
||||||
|
}
|
||||||
if (dpl->dp.hostlist_auto)
|
if (dpl->dp.hostlist_auto)
|
||||||
DLOG("profile %d auto hostlist %s%s\n",dpl->dp.n,dpl->dp.hostlist_auto->filename,dpl->dp.hostlist_auto->hostlist ? "" : " (empty)");
|
DLOG("profile %d auto hostlist %s%s\n",dpl->dp.n,dpl->dp.hostlist_auto->filename,dpl->dp.hostlist_auto->hostlist ? "" : " (empty)");
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,14 @@
|
|||||||
#include "pools.h"
|
#include "pools.h"
|
||||||
#include "params.h"
|
#include "params.h"
|
||||||
|
|
||||||
bool AppendHostList(strpool **hostlist, const char *filename);
|
bool AppendHostlistItem(hostlist_pool **hostlist, char *s);
|
||||||
|
bool AppendHostList(hostlist_pool **hostlist, const char *filename);
|
||||||
bool LoadAllHostLists();
|
bool LoadAllHostLists();
|
||||||
bool NonEmptyHostlist(strpool **hostlist);
|
bool NonEmptyHostlist(hostlist_pool **hostlist);
|
||||||
// return : true = apply fooling, false = do not apply
|
// return : true = apply fooling, false = do not apply
|
||||||
bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *excluded, bool bSkipReloadCheck);
|
bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *excluded, bool bSkipReloadCheck);
|
||||||
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename);
|
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename);
|
||||||
bool HostlistsReloadCheckForProfile(const struct desync_profile *dp);
|
bool HostlistsReloadCheckForProfile(const struct desync_profile *dp);
|
||||||
void HostlistsDebug();
|
void HostlistsDebug();
|
||||||
|
|
||||||
|
#define ResetAllHostlistsModTime() hostlist_files_reset_modtime(¶ms.hostlists)
|
||||||
|
76
nfq/ipset.c
76
nfq/ipset.c
@ -31,7 +31,7 @@ static bool addpool(ipset *ips, char **s, const char *end, int *ct)
|
|||||||
ipsetDestroy(ips);
|
ipsetDestroy(ips);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
(*ct)++;
|
if (ct) (*ct)++;
|
||||||
}
|
}
|
||||||
else if (parse_cidr6(cidr,&c6))
|
else if (parse_cidr6(cidr,&c6))
|
||||||
{
|
{
|
||||||
@ -40,7 +40,7 @@ static bool addpool(ipset *ips, char **s, const char *end, int *ct)
|
|||||||
ipsetDestroy(ips);
|
ipsetDestroy(ips);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
(*ct)++;
|
if (ct) (*ct)++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
DLOG_ERR("bad ip or subnet : %s\n",cidr);
|
DLOG_ERR("bad ip or subnet : %s\n",cidr);
|
||||||
@ -53,6 +53,11 @@ static bool addpool(ipset *ips, char **s, const char *end, int *ct)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AppendIpsetItem(ipset *ips, char *ip)
|
||||||
|
{
|
||||||
|
return addpool(ips,&ip,ip+strlen(ip),NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static bool AppendIpset(ipset *ips, const char *filename)
|
static bool AppendIpset(ipset *ips, const char *filename)
|
||||||
{
|
{
|
||||||
char *p, *e, s[256], *zbuf;
|
char *p, *e, s[256], *zbuf;
|
||||||
@ -119,21 +124,25 @@ static bool AppendIpset(ipset *ips, const char *filename)
|
|||||||
|
|
||||||
static bool LoadIpset(struct ipset_file *hfile)
|
static bool LoadIpset(struct ipset_file *hfile)
|
||||||
{
|
{
|
||||||
time_t t = file_mod_time(hfile->filename);
|
if (hfile->filename)
|
||||||
if (!t)
|
|
||||||
{
|
|
||||||
// stat() error
|
|
||||||
DLOG_ERR("cannot access ipset file '%s'. in-memory content remains unchanged.\n",hfile->filename);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (t==hfile->mod_time) return true; // up to date
|
|
||||||
ipsetDestroy(&hfile->ipset);
|
|
||||||
if (!AppendIpset(&hfile->ipset, hfile->filename))
|
|
||||||
{
|
{
|
||||||
|
file_mod_sig fsig;
|
||||||
|
if (!file_mod_signature(hfile->filename, &fsig))
|
||||||
|
{
|
||||||
|
// stat() error
|
||||||
|
DLOG_PERROR("file_mod_signature");
|
||||||
|
DLOG_ERR("cannot access ipset file '%s'. in-memory content remains unchanged.\n",hfile->filename);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (FILE_MOD_COMPARE(&hfile->mod_sig,&fsig)) return true; // up to date
|
||||||
ipsetDestroy(&hfile->ipset);
|
ipsetDestroy(&hfile->ipset);
|
||||||
return false;
|
if (!AppendIpset(&hfile->ipset, hfile->filename))
|
||||||
|
{
|
||||||
|
ipsetDestroy(&hfile->ipset);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
hfile->mod_sig=fsig;
|
||||||
}
|
}
|
||||||
hfile->mod_time=t;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
static bool LoadIpsets(struct ipset_files_head *list)
|
static bool LoadIpsets(struct ipset_files_head *list)
|
||||||
@ -205,7 +214,7 @@ static bool IpsetCheck_(const struct ipset_collection_head *ips, const struct ip
|
|||||||
|
|
||||||
LIST_FOREACH(item, ips_exclude, next)
|
LIST_FOREACH(item, ips_exclude, next)
|
||||||
{
|
{
|
||||||
DLOG("[%s] exclude ",item->hfile->filename);
|
DLOG("[%s] exclude ",item->hfile->filename ? item->hfile->filename : "fixed");
|
||||||
if (SearchIpset(&item->hfile->ipset, ipv4, ipv6))
|
if (SearchIpset(&item->hfile->ipset, ipv4, ipv6))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -214,7 +223,7 @@ static bool IpsetCheck_(const struct ipset_collection_head *ips, const struct ip
|
|||||||
{
|
{
|
||||||
LIST_FOREACH(item, ips, next)
|
LIST_FOREACH(item, ips, next)
|
||||||
{
|
{
|
||||||
DLOG("[%s] include ",item->hfile->filename);
|
DLOG("[%s] include ",item->hfile->filename ? item->hfile->filename : "fixed");
|
||||||
if (SearchIpset(&item->hfile->ipset, ipv4, ipv6))
|
if (SearchIpset(&item->hfile->ipset, ipv4, ipv6))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -234,17 +243,27 @@ bool IpsetCheck(const struct desync_profile *dp, const struct in_addr *ipv4, con
|
|||||||
static struct ipset_file *RegisterIpset_(struct ipset_files_head *ipsets, struct ipset_collection_head *ips_collection, const char *filename)
|
static struct ipset_file *RegisterIpset_(struct ipset_files_head *ipsets, struct ipset_collection_head *ips_collection, const char *filename)
|
||||||
{
|
{
|
||||||
struct ipset_file *hfile;
|
struct ipset_file *hfile;
|
||||||
if (!(hfile=ipset_files_search(ipsets, filename)))
|
if (filename)
|
||||||
if (!(hfile=ipset_files_add(ipsets, filename)))
|
{
|
||||||
|
if (!(hfile=ipset_files_search(ipsets, filename)))
|
||||||
|
if (!(hfile=ipset_files_add(ipsets, filename)))
|
||||||
|
return NULL;
|
||||||
|
if (!ipset_collection_search(ips_collection, filename))
|
||||||
|
if (!ipset_collection_add(ips_collection, hfile))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(hfile=ipset_files_add(ipsets, NULL)))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!ipset_collection_search(ips_collection, filename))
|
|
||||||
if (!ipset_collection_add(ips_collection, hfile))
|
if (!ipset_collection_add(ips_collection, hfile))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
return hfile;
|
return hfile;
|
||||||
}
|
}
|
||||||
struct ipset_file *RegisterIpset(struct desync_profile *dp, bool bExclude, const char *filename)
|
struct ipset_file *RegisterIpset(struct desync_profile *dp, bool bExclude, const char *filename)
|
||||||
{
|
{
|
||||||
if (!file_mod_time(filename))
|
if (filename && !file_mod_time(filename))
|
||||||
{
|
{
|
||||||
DLOG_ERR("cannot access ipset file '%s'\n",filename);
|
DLOG_ERR("cannot access ipset file '%s'\n",filename);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -277,13 +296,24 @@ void IpsetsDebug()
|
|||||||
struct ipset_item *ips_item;
|
struct ipset_item *ips_item;
|
||||||
|
|
||||||
LIST_FOREACH(hfile, ¶ms.ipsets, next)
|
LIST_FOREACH(hfile, ¶ms.ipsets, next)
|
||||||
DLOG("ipset file %s (%s)\n",hfile->filename,dbg_ipset_fill(&hfile->ipset));
|
{
|
||||||
|
if (hfile->filename)
|
||||||
|
DLOG("ipset file %s (%s)\n",hfile->filename,dbg_ipset_fill(&hfile->ipset));
|
||||||
|
else
|
||||||
|
DLOG("ipset fixed (%s)\n",dbg_ipset_fill(&hfile->ipset));
|
||||||
|
}
|
||||||
|
|
||||||
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
||||||
{
|
{
|
||||||
LIST_FOREACH(ips_item, &dpl->dp.ips_collection, next)
|
LIST_FOREACH(ips_item, &dpl->dp.ips_collection, next)
|
||||||
DLOG("profile %d include ipset %s (%s)\n",dpl->dp.n,ips_item->hfile->filename,dbg_ipset_fill(&ips_item->hfile->ipset));
|
if (ips_item->hfile->filename)
|
||||||
|
DLOG("profile %d include ipset %s (%s)\n",dpl->dp.n,ips_item->hfile->filename,dbg_ipset_fill(&ips_item->hfile->ipset));
|
||||||
|
else
|
||||||
|
DLOG("profile %d include fixed ipset (%s)\n",dpl->dp.n,dbg_ipset_fill(&ips_item->hfile->ipset));
|
||||||
LIST_FOREACH(ips_item, &dpl->dp.ips_collection_exclude, next)
|
LIST_FOREACH(ips_item, &dpl->dp.ips_collection_exclude, next)
|
||||||
DLOG("profile %d exclude ipset %s (%s)\n",dpl->dp.n,ips_item->hfile->filename,dbg_ipset_fill(&ips_item->hfile->ipset));
|
if (ips_item->hfile->filename)
|
||||||
|
DLOG("profile %d exclude ipset %s (%s)\n",dpl->dp.n,ips_item->hfile->filename,dbg_ipset_fill(&ips_item->hfile->ipset));
|
||||||
|
else
|
||||||
|
DLOG("profile %d exclude fixed ipset (%s)\n",dpl->dp.n,dbg_ipset_fill(&ips_item->hfile->ipset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,3 +9,6 @@ bool LoadAllIpsets();
|
|||||||
bool IpsetCheck(const struct desync_profile *dp, const struct in_addr *ipv4, const struct in6_addr *ipv6);
|
bool IpsetCheck(const struct desync_profile *dp, const struct in_addr *ipv4, const struct in6_addr *ipv6);
|
||||||
struct ipset_file *RegisterIpset(struct desync_profile *dp, bool bExclude, const char *filename);
|
struct ipset_file *RegisterIpset(struct desync_profile *dp, bool bExclude, const char *filename);
|
||||||
void IpsetsDebug();
|
void IpsetsDebug();
|
||||||
|
bool AppendIpsetItem(ipset *ips, char *ip);
|
||||||
|
|
||||||
|
#define ResetAllIpsetModTime() ipset_files_reset_modtime(¶ms.ipsets)
|
||||||
|
1207
nfq/nfqws.c
1207
nfq/nfqws.c
File diff suppressed because it is too large
Load Diff
128
nfq/params.c
128
nfq/params.c
@ -65,6 +65,7 @@ static int DLOG_VA(const char *format, int syslog_priority, bool condup, va_list
|
|||||||
{
|
{
|
||||||
va_copy(args2,args);
|
va_copy(args2,args);
|
||||||
DLOG_CON(format,syslog_priority,args2);
|
DLOG_CON(format,syslog_priority,args2);
|
||||||
|
va_end(args2);
|
||||||
}
|
}
|
||||||
if (params.debug)
|
if (params.debug)
|
||||||
{
|
{
|
||||||
@ -170,45 +171,77 @@ void hexdump_limited_dlog(const uint8_t *data, size_t size, size_t limit)
|
|||||||
if (bcut) DLOG(" ...");
|
if (bcut) DLOG(" ...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dp_init(struct desync_profile *dp)
|
||||||
|
{
|
||||||
|
LIST_INIT(&dp->hl_collection);
|
||||||
|
LIST_INIT(&dp->hl_collection_exclude);
|
||||||
|
LIST_INIT(&dp->ips_collection);
|
||||||
|
LIST_INIT(&dp->ips_collection_exclude);
|
||||||
|
LIST_INIT(&dp->pf_tcp);
|
||||||
|
LIST_INIT(&dp->pf_udp);
|
||||||
|
|
||||||
|
memcpy(dp->hostspell, "host", 4); // default hostspell
|
||||||
|
dp->desync_skip_nosni = true;
|
||||||
|
dp->desync_ipfrag_pos_udp = IPFRAG_UDP_DEFAULT;
|
||||||
|
dp->desync_ipfrag_pos_tcp = IPFRAG_TCP_DEFAULT;
|
||||||
|
dp->desync_repeats = 1;
|
||||||
|
dp->fake_syndata_size = 16;
|
||||||
|
dp->wscale=-1; // default - dont change scale factor (client)
|
||||||
|
dp->desync_ttl6 = 0xFF; // unused
|
||||||
|
dp->desync_badseq_increment = BADSEQ_INCREMENT_DEFAULT;
|
||||||
|
dp->desync_badseq_ack_increment = BADSEQ_ACK_INCREMENT_DEFAULT;
|
||||||
|
dp->wssize_cutoff_mode = dp->desync_start_mode = dp->desync_cutoff_mode = 'n'; // packet number by default
|
||||||
|
dp->udplen_increment = UDPLEN_INCREMENT_DEFAULT;
|
||||||
|
dp->hostlist_auto_fail_threshold = HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT;
|
||||||
|
dp->hostlist_auto_fail_time = HOSTLIST_AUTO_FAIL_TIME_DEFAULT;
|
||||||
|
dp->hostlist_auto_retrans_threshold = HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT;
|
||||||
|
dp->filter_ipv4 = dp->filter_ipv6 = true;
|
||||||
|
}
|
||||||
|
bool dp_fake_defaults(struct desync_profile *dp)
|
||||||
|
{
|
||||||
|
struct blob_item *item;
|
||||||
|
if (blob_collection_empty(&dp->fake_http))
|
||||||
|
if (!blob_collection_add_blob(&dp->fake_http,fake_http_request_default,strlen(fake_http_request_default),0))
|
||||||
|
return false;
|
||||||
|
if (blob_collection_empty(&dp->fake_tls))
|
||||||
|
{
|
||||||
|
if (!(item=blob_collection_add_blob(&dp->fake_tls,fake_tls_clienthello_default,sizeof(fake_tls_clienthello_default),4+sizeof(((struct fake_tls_mod*)0)->sni))))
|
||||||
|
return false;
|
||||||
|
if (!(item->extra2 = malloc(sizeof(struct fake_tls_mod))))
|
||||||
|
return false;
|
||||||
|
*(struct fake_tls_mod*)item->extra2 = dp->tls_mod_last;
|
||||||
|
}
|
||||||
|
if (blob_collection_empty(&dp->fake_unknown))
|
||||||
|
{
|
||||||
|
if (!(item=blob_collection_add_blob(&dp->fake_unknown,NULL,256,0)))
|
||||||
|
return false;
|
||||||
|
memset(item->data,0,item->size);
|
||||||
|
}
|
||||||
|
if (blob_collection_empty(&dp->fake_quic))
|
||||||
|
{
|
||||||
|
if (!(item=blob_collection_add_blob(&dp->fake_quic,NULL,620,0)))
|
||||||
|
return false;
|
||||||
|
memset(item->data,0,item->size);
|
||||||
|
item->data[0] = 0x40;
|
||||||
|
}
|
||||||
|
struct blob_collection_head **fake,*fakes_z64[] = {&dp->fake_wg, &dp->fake_dht, &dp->fake_discord, &dp->fake_stun, &dp->fake_unknown_udp,NULL};
|
||||||
|
for(fake=fakes_z64;*fake;fake++)
|
||||||
|
{
|
||||||
|
if (blob_collection_empty(*fake))
|
||||||
|
{
|
||||||
|
if (!(item=blob_collection_add_blob(*fake,NULL,64,0)))
|
||||||
|
return false;
|
||||||
|
memset(item->data,0,item->size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
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 = calloc(1,sizeof(struct desync_profile_list));
|
struct desync_profile_list *entry = calloc(1,sizeof(struct desync_profile_list));
|
||||||
if (!entry) return NULL;
|
if (!entry) return NULL;
|
||||||
|
|
||||||
LIST_INIT(&entry->dp.hl_collection);
|
|
||||||
LIST_INIT(&entry->dp.hl_collection_exclude);
|
|
||||||
LIST_INIT(&entry->dp.ips_collection);
|
|
||||||
LIST_INIT(&entry->dp.ips_collection_exclude);
|
|
||||||
LIST_INIT(&entry->dp.pf_tcp);
|
|
||||||
LIST_INIT(&entry->dp.pf_udp);
|
|
||||||
|
|
||||||
memcpy(entry->dp.hostspell, "host", 4); // default hostspell
|
dp_init(&entry->dp);
|
||||||
entry->dp.desync_skip_nosni = true;
|
|
||||||
entry->dp.desync_ipfrag_pos_udp = IPFRAG_UDP_DEFAULT;
|
|
||||||
entry->dp.desync_ipfrag_pos_tcp = IPFRAG_TCP_DEFAULT;
|
|
||||||
entry->dp.desync_repeats = 1;
|
|
||||||
entry->dp.fake_tls_size = sizeof(fake_tls_clienthello_default);
|
|
||||||
memcpy(entry->dp.fake_tls,fake_tls_clienthello_default,entry->dp.fake_tls_size);
|
|
||||||
randomize_default_tls_payload(entry->dp.fake_tls);
|
|
||||||
entry->dp.fake_http_size = strlen(fake_http_request_default);
|
|
||||||
memcpy(entry->dp.fake_http,fake_http_request_default,entry->dp.fake_http_size);
|
|
||||||
entry->dp.fake_quic_size = 620; // must be 601+ for TSPU hack
|
|
||||||
entry->dp.fake_quic[0] = 0x40; // russian TSPU QUIC short header fake
|
|
||||||
entry->dp.fake_wg_size = 64;
|
|
||||||
entry->dp.fake_dht_size = 64;
|
|
||||||
entry->dp.fake_unknown_size = 256;
|
|
||||||
entry->dp.fake_syndata_size = 16;
|
|
||||||
entry->dp.fake_unknown_udp_size = 64;
|
|
||||||
entry->dp.wscale=-1; // default - dont change scale factor (client)
|
|
||||||
entry->dp.desync_ttl6 = 0xFF; // unused
|
|
||||||
entry->dp.desync_badseq_increment = BADSEQ_INCREMENT_DEFAULT;
|
|
||||||
entry->dp.desync_badseq_ack_increment = BADSEQ_ACK_INCREMENT_DEFAULT;
|
|
||||||
entry->dp.wssize_cutoff_mode = entry->dp.desync_start_mode = entry->dp.desync_cutoff_mode = 'n'; // packet number by default
|
|
||||||
entry->dp.udplen_increment = UDPLEN_INCREMENT_DEFAULT;
|
|
||||||
entry->dp.hostlist_auto_fail_threshold = HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT;
|
|
||||||
entry->dp.hostlist_auto_fail_time = HOSTLIST_AUTO_FAIL_TIME_DEFAULT;
|
|
||||||
entry->dp.hostlist_auto_retrans_threshold = HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT;
|
|
||||||
entry->dp.filter_ipv4 = entry->dp.filter_ipv6 = true;
|
|
||||||
|
|
||||||
// add to the tail
|
// add to the tail
|
||||||
struct desync_profile_list *dpn,*dpl=LIST_FIRST(¶ms.desync_profiles);
|
struct desync_profile_list *dpn,*dpl=LIST_FIRST(¶ms.desync_profiles);
|
||||||
@ -222,15 +255,26 @@ struct desync_profile_list *dp_list_add(struct desync_profile_list_head *head)
|
|||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
static void dp_entry_destroy(struct desync_profile_list *entry)
|
static void dp_clear_dynamic(struct desync_profile *dp)
|
||||||
{
|
{
|
||||||
hostlist_collection_destroy(&entry->dp.hl_collection);
|
hostlist_collection_destroy(&dp->hl_collection);
|
||||||
hostlist_collection_destroy(&entry->dp.hl_collection_exclude);
|
hostlist_collection_destroy(&dp->hl_collection_exclude);
|
||||||
ipset_collection_destroy(&entry->dp.ips_collection);
|
ipset_collection_destroy(&dp->ips_collection);
|
||||||
ipset_collection_destroy(&entry->dp.ips_collection_exclude);
|
ipset_collection_destroy(&dp->ips_collection_exclude);
|
||||||
port_filters_destroy(&entry->dp.pf_tcp);
|
port_filters_destroy(&dp->pf_tcp);
|
||||||
port_filters_destroy(&entry->dp.pf_udp);
|
port_filters_destroy(&dp->pf_udp);
|
||||||
HostFailPoolDestroy(&entry->dp.hostlist_auto_fail_counters);
|
HostFailPoolDestroy(&dp->hostlist_auto_fail_counters);
|
||||||
|
struct blob_collection_head **fake,*fakes[] = {&dp->fake_http, &dp->fake_tls, &dp->fake_unknown, &dp->fake_unknown_udp, &dp->fake_quic, &dp->fake_wg, &dp->fake_dht, &dp->fake_discord, &dp->fake_stun, NULL};
|
||||||
|
for(fake=fakes;*fake;fake++) blob_collection_destroy(*fake);
|
||||||
|
}
|
||||||
|
void dp_clear(struct desync_profile *dp)
|
||||||
|
{
|
||||||
|
dp_clear_dynamic(dp);
|
||||||
|
memset(dp,0,sizeof(*dp));
|
||||||
|
}
|
||||||
|
void dp_entry_destroy(struct desync_profile_list *entry)
|
||||||
|
{
|
||||||
|
dp_clear_dynamic(&entry->dp);
|
||||||
free(entry);
|
free(entry);
|
||||||
}
|
}
|
||||||
void dp_list_destroy(struct desync_profile_list_head *head)
|
void dp_list_destroy(struct desync_profile_list_head *head)
|
||||||
|
41
nfq/params.h
41
nfq/params.h
@ -20,8 +20,6 @@
|
|||||||
|
|
||||||
#define TLS_PARTIALS_ENABLE true
|
#define TLS_PARTIALS_ENABLE true
|
||||||
|
|
||||||
#define Q_RCVBUF (128*1024) // in bytes
|
|
||||||
#define Q_SNDBUF (64*1024) // in bytes
|
|
||||||
#define RAW_SNDBUF (64*1024) // in bytes
|
#define RAW_SNDBUF (64*1024) // in bytes
|
||||||
|
|
||||||
#define Q_MAXLEN 1024 // in packets
|
#define Q_MAXLEN 1024 // in packets
|
||||||
@ -40,8 +38,30 @@
|
|||||||
|
|
||||||
#define MAX_SPLITS 64
|
#define MAX_SPLITS 64
|
||||||
|
|
||||||
|
#define FAKE_TLS_MOD_SAVE_MASK 0x0F
|
||||||
|
#define FAKE_TLS_MOD_SET 0x01
|
||||||
|
#define FAKE_TLS_MOD_CUSTOM_FAKE 0x02
|
||||||
|
#define FAKE_TLS_MOD_RND 0x10
|
||||||
|
#define FAKE_TLS_MOD_DUP_SID 0x20
|
||||||
|
#define FAKE_TLS_MOD_RND_SNI 0x40
|
||||||
|
#define FAKE_TLS_MOD_SNI 0x80
|
||||||
|
#define FAKE_TLS_MOD_PADENCAP 0x100
|
||||||
|
|
||||||
|
#define FAKE_MAX_TCP 1460
|
||||||
|
#define FAKE_MAX_UDP 1472
|
||||||
|
|
||||||
enum log_target { LOG_TARGET_CONSOLE=0, LOG_TARGET_FILE, LOG_TARGET_SYSLOG };
|
enum log_target { LOG_TARGET_CONSOLE=0, LOG_TARGET_FILE, LOG_TARGET_SYSLOG };
|
||||||
|
|
||||||
|
struct fake_tls_mod_cache
|
||||||
|
{
|
||||||
|
size_t extlen_offset, padlen_offset;
|
||||||
|
};
|
||||||
|
struct fake_tls_mod
|
||||||
|
{
|
||||||
|
char sni[64];
|
||||||
|
uint32_t mod;
|
||||||
|
};
|
||||||
|
|
||||||
struct desync_profile
|
struct desync_profile
|
||||||
{
|
{
|
||||||
int n; // number of the profile
|
int n; // number of the profile
|
||||||
@ -51,7 +71,7 @@ struct desync_profile
|
|||||||
char wssize_cutoff_mode; // n - packets, d - data packets, s - relative sequence
|
char wssize_cutoff_mode; // n - packets, d - data packets, s - relative sequence
|
||||||
unsigned int wssize_cutoff;
|
unsigned int wssize_cutoff;
|
||||||
|
|
||||||
bool hostcase, hostnospace, domcase;
|
bool hostcase, hostnospace, domcase, methodeol;
|
||||||
char hostspell[4];
|
char hostspell[4];
|
||||||
enum dpi_desync_mode desync_mode0,desync_mode,desync_mode2;
|
enum dpi_desync_mode desync_mode0,desync_mode,desync_mode2;
|
||||||
bool desync_retrans,desync_skip_nosni,desync_any_proto;
|
bool desync_retrans,desync_skip_nosni,desync_any_proto;
|
||||||
@ -68,9 +88,14 @@ struct desync_profile
|
|||||||
autottl desync_autottl, desync_autottl6;
|
autottl desync_autottl, desync_autottl6;
|
||||||
uint32_t desync_fooling_mode;
|
uint32_t desync_fooling_mode;
|
||||||
uint32_t desync_badseq_increment, desync_badseq_ack_increment;
|
uint32_t desync_badseq_increment, desync_badseq_ack_increment;
|
||||||
uint8_t fake_http[1460],fake_tls[1460],fake_unknown[1460],fake_syndata[1460],seqovl_pattern[1460];
|
|
||||||
uint8_t fake_unknown_udp[1472],udplen_pattern[1472],fake_quic[1472],fake_wg[1472],fake_dht[1472];
|
struct blob_collection_head fake_http,fake_tls,fake_unknown,fake_unknown_udp,fake_quic,fake_wg,fake_dht,fake_discord,fake_stun;
|
||||||
size_t fake_http_size,fake_tls_size,fake_quic_size,fake_wg_size,fake_dht_size,fake_unknown_size,fake_syndata_size,fake_unknown_udp_size;
|
uint8_t fake_syndata[FAKE_MAX_TCP],seqovl_pattern[FAKE_MAX_TCP],fsplit_pattern[FAKE_MAX_TCP],udplen_pattern[FAKE_MAX_UDP];
|
||||||
|
size_t fake_syndata_size;
|
||||||
|
|
||||||
|
struct fake_tls_mod tls_mod_last;
|
||||||
|
struct blob_item *tls_fake_last;
|
||||||
|
|
||||||
int udplen_increment;
|
int udplen_increment;
|
||||||
|
|
||||||
bool filter_ipv4,filter_ipv6;
|
bool filter_ipv4,filter_ipv6;
|
||||||
@ -99,8 +124,12 @@ struct desync_profile_list {
|
|||||||
};
|
};
|
||||||
LIST_HEAD(desync_profile_list_head, desync_profile_list);
|
LIST_HEAD(desync_profile_list_head, desync_profile_list);
|
||||||
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);
|
||||||
|
void dp_entry_destroy(struct desync_profile_list *entry);
|
||||||
void dp_list_destroy(struct desync_profile_list_head *head);
|
void dp_list_destroy(struct desync_profile_list_head *head);
|
||||||
bool dp_list_have_autohostlist(struct desync_profile_list_head *head);
|
bool dp_list_have_autohostlist(struct desync_profile_list_head *head);
|
||||||
|
void dp_init(struct desync_profile *dp);
|
||||||
|
bool dp_fake_defaults(struct desync_profile *dp);
|
||||||
|
void dp_clear(struct desync_profile *dp);
|
||||||
|
|
||||||
struct params_s
|
struct params_s
|
||||||
{
|
{
|
||||||
|
144
nfq/pools.c
144
nfq/pools.c
@ -31,6 +31,9 @@
|
|||||||
free(elem); \
|
free(elem); \
|
||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
|
#define ADD_HOSTLIST_POOL(etype, ppool, keystr, keystr_len, flg) \
|
||||||
|
ADD_STR_POOL(etype,ppool,keystr,keystr_len); \
|
||||||
|
elem->flags = flg;
|
||||||
|
|
||||||
|
|
||||||
#undef uthash_nonfatal_oom
|
#undef uthash_nonfatal_oom
|
||||||
@ -42,27 +45,31 @@ static void ut_oom_recover(void *elem)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for not zero terminated strings
|
// for not zero terminated strings
|
||||||
bool StrPoolAddStrLen(strpool **pp, const char *s, size_t slen)
|
bool HostlistPoolAddStrLen(hostlist_pool **pp, const char *s, size_t slen, uint32_t flags)
|
||||||
{
|
{
|
||||||
ADD_STR_POOL(strpool, pp, s, slen)
|
ADD_HOSTLIST_POOL(hostlist_pool, pp, s, slen, flags)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// for zero terminated strings
|
// for zero terminated strings
|
||||||
bool StrPoolAddStr(strpool **pp, const char *s)
|
bool HostlistPoolAddStr(hostlist_pool **pp, const char *s, uint32_t flags)
|
||||||
{
|
{
|
||||||
return StrPoolAddStrLen(pp, s, strlen(s));
|
return HostlistPoolAddStrLen(pp, s, strlen(s), flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StrPoolCheckStr(strpool *p, const char *s)
|
hostlist_pool *HostlistPoolGetStr(hostlist_pool *p, const char *s)
|
||||||
{
|
{
|
||||||
strpool *elem;
|
hostlist_pool *elem;
|
||||||
HASH_FIND_STR(p, s, elem);
|
HASH_FIND_STR(p, s, elem);
|
||||||
return elem != NULL;
|
return elem;
|
||||||
|
}
|
||||||
|
bool HostlistPoolCheckStr(hostlist_pool *p, const char *s)
|
||||||
|
{
|
||||||
|
return !!HostlistPoolGetStr(p,s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StrPoolDestroy(strpool **pp)
|
void HostlistPoolDestroy(hostlist_pool **pp)
|
||||||
{
|
{
|
||||||
DESTROY_STR_POOL(strpool, pp)
|
DESTROY_STR_POOL(hostlist_pool, pp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -139,7 +146,7 @@ bool strlist_add(struct str_list_head *head, const char *filename)
|
|||||||
}
|
}
|
||||||
static void strlist_entry_destroy(struct str_list *entry)
|
static void strlist_entry_destroy(struct str_list *entry)
|
||||||
{
|
{
|
||||||
if (entry->str) free(entry->str);
|
free(entry->str);
|
||||||
free(entry);
|
free(entry);
|
||||||
}
|
}
|
||||||
void strlist_destroy(struct str_list_head *head)
|
void strlist_destroy(struct str_list_head *head)
|
||||||
@ -154,18 +161,22 @@ void strlist_destroy(struct str_list_head *head)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const char *filename)
|
struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const char *filename)
|
||||||
{
|
{
|
||||||
struct hostlist_file *entry = malloc(sizeof(struct hostlist_file));
|
struct hostlist_file *entry = malloc(sizeof(struct hostlist_file));
|
||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
if (!(entry->filename = strdup(filename)))
|
if (filename)
|
||||||
{
|
{
|
||||||
free(entry);
|
if (!(entry->filename = strdup(filename)))
|
||||||
return false;
|
{
|
||||||
|
free(entry);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
entry->mod_time=0;
|
else
|
||||||
|
entry->filename = NULL;
|
||||||
|
FILE_MOD_RESET(&entry->mod_sig);
|
||||||
entry->hostlist = NULL;
|
entry->hostlist = NULL;
|
||||||
LIST_INSERT_HEAD(head, entry, next);
|
LIST_INSERT_HEAD(head, entry, next);
|
||||||
}
|
}
|
||||||
@ -173,8 +184,8 @@ struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const
|
|||||||
}
|
}
|
||||||
static void hostlist_files_entry_destroy(struct hostlist_file *entry)
|
static void hostlist_files_entry_destroy(struct hostlist_file *entry)
|
||||||
{
|
{
|
||||||
if (entry->filename) free(entry->filename);
|
free(entry->filename);
|
||||||
StrPoolDestroy(&entry->hostlist);
|
HostlistPoolDestroy(&entry->hostlist);
|
||||||
free(entry);
|
free(entry);
|
||||||
}
|
}
|
||||||
void hostlist_files_destroy(struct hostlist_files_head *head)
|
void hostlist_files_destroy(struct hostlist_files_head *head)
|
||||||
@ -192,11 +203,18 @@ struct hostlist_file *hostlist_files_search(struct hostlist_files_head *head, co
|
|||||||
|
|
||||||
LIST_FOREACH(hfile, head, next)
|
LIST_FOREACH(hfile, head, next)
|
||||||
{
|
{
|
||||||
if (!strcmp(hfile->filename,filename))
|
if (hfile->filename && !strcmp(hfile->filename,filename))
|
||||||
return hfile;
|
return hfile;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
void hostlist_files_reset_modtime(struct hostlist_files_head *list)
|
||||||
|
{
|
||||||
|
struct hostlist_file *hfile;
|
||||||
|
|
||||||
|
LIST_FOREACH(hfile, list, next)
|
||||||
|
FILE_MOD_RESET(&hfile->mod_sig);
|
||||||
|
}
|
||||||
|
|
||||||
struct hostlist_item *hostlist_collection_add(struct hostlist_collection_head *head, struct hostlist_file *hfile)
|
struct hostlist_item *hostlist_collection_add(struct hostlist_collection_head *head, struct hostlist_file *hfile)
|
||||||
{
|
{
|
||||||
@ -223,7 +241,7 @@ struct hostlist_item *hostlist_collection_search(struct hostlist_collection_head
|
|||||||
|
|
||||||
LIST_FOREACH(item, head, next)
|
LIST_FOREACH(item, head, next)
|
||||||
{
|
{
|
||||||
if (!strcmp(item->hfile->filename,filename))
|
if (item->hfile->filename && !strcmp(item->hfile->filename,filename))
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -369,12 +387,17 @@ struct ipset_file *ipset_files_add(struct ipset_files_head *head, const char *fi
|
|||||||
struct ipset_file *entry = malloc(sizeof(struct ipset_file));
|
struct ipset_file *entry = malloc(sizeof(struct ipset_file));
|
||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
if (!(entry->filename = strdup(filename)))
|
if (filename)
|
||||||
{
|
{
|
||||||
free(entry);
|
if (!(entry->filename = strdup(filename)))
|
||||||
return false;
|
{
|
||||||
|
free(entry);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
entry->mod_time=0;
|
else
|
||||||
|
entry->filename = NULL;
|
||||||
|
FILE_MOD_RESET(&entry->mod_sig);
|
||||||
memset(&entry->ipset,0,sizeof(entry->ipset));
|
memset(&entry->ipset,0,sizeof(entry->ipset));
|
||||||
LIST_INSERT_HEAD(head, entry, next);
|
LIST_INSERT_HEAD(head, entry, next);
|
||||||
}
|
}
|
||||||
@ -382,7 +405,7 @@ struct ipset_file *ipset_files_add(struct ipset_files_head *head, const char *fi
|
|||||||
}
|
}
|
||||||
static void ipset_files_entry_destroy(struct ipset_file *entry)
|
static void ipset_files_entry_destroy(struct ipset_file *entry)
|
||||||
{
|
{
|
||||||
if (entry->filename) free(entry->filename);
|
free(entry->filename);
|
||||||
ipsetDestroy(&entry->ipset);
|
ipsetDestroy(&entry->ipset);
|
||||||
free(entry);
|
free(entry);
|
||||||
}
|
}
|
||||||
@ -401,11 +424,18 @@ struct ipset_file *ipset_files_search(struct ipset_files_head *head, const char
|
|||||||
|
|
||||||
LIST_FOREACH(hfile, head, next)
|
LIST_FOREACH(hfile, head, next)
|
||||||
{
|
{
|
||||||
if (!strcmp(hfile->filename,filename))
|
if (hfile->filename && !strcmp(hfile->filename,filename))
|
||||||
return hfile;
|
return hfile;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
void ipset_files_reset_modtime(struct ipset_files_head *list)
|
||||||
|
{
|
||||||
|
struct ipset_file *hfile;
|
||||||
|
|
||||||
|
LIST_FOREACH(hfile, list, next)
|
||||||
|
FILE_MOD_RESET(&hfile->mod_sig);
|
||||||
|
}
|
||||||
|
|
||||||
struct ipset_item *ipset_collection_add(struct ipset_collection_head *head, struct ipset_file *hfile)
|
struct ipset_item *ipset_collection_add(struct ipset_collection_head *head, struct ipset_file *hfile)
|
||||||
{
|
{
|
||||||
@ -432,7 +462,7 @@ struct ipset_item *ipset_collection_search(struct ipset_collection_head *head, c
|
|||||||
|
|
||||||
LIST_FOREACH(item, head, next)
|
LIST_FOREACH(item, head, next)
|
||||||
{
|
{
|
||||||
if (!strcmp(item->hfile->filename,filename))
|
if (item->hfile->filename && !strcmp(item->hfile->filename,filename))
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -487,3 +517,65 @@ bool port_filters_deny_if_empty(struct port_filters_head *head)
|
|||||||
if (LIST_FIRST(head)) return true;
|
if (LIST_FIRST(head)) return true;
|
||||||
return pf_parse("0",&pf) && port_filter_add(head,&pf);
|
return pf_parse("0",&pf) && port_filter_add(head,&pf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct blob_item *blob_collection_add(struct blob_collection_head *head)
|
||||||
|
{
|
||||||
|
struct blob_item *entry = calloc(1,sizeof(struct blob_item));
|
||||||
|
if (entry)
|
||||||
|
{
|
||||||
|
// insert to the end
|
||||||
|
struct blob_item *itemc,*iteml=LIST_FIRST(head);
|
||||||
|
if (iteml)
|
||||||
|
{
|
||||||
|
while ((itemc=LIST_NEXT(iteml,next))) iteml = itemc;
|
||||||
|
LIST_INSERT_AFTER(iteml, entry, next);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LIST_INSERT_HEAD(head, entry, next);
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
struct blob_item *blob_collection_add_blob(struct blob_collection_head *head, const void *data, size_t size, size_t size_reserve)
|
||||||
|
{
|
||||||
|
struct blob_item *entry = calloc(1,sizeof(struct blob_item));
|
||||||
|
if (!entry) return NULL;
|
||||||
|
if (!(entry->data = malloc(size+size_reserve)))
|
||||||
|
{
|
||||||
|
free(entry);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (data) memcpy(entry->data,data,size);
|
||||||
|
entry->size = size;
|
||||||
|
entry->size_buf = size+size_reserve;
|
||||||
|
|
||||||
|
// insert to the end
|
||||||
|
struct blob_item *itemc,*iteml=LIST_FIRST(head);
|
||||||
|
if (iteml)
|
||||||
|
{
|
||||||
|
while ((itemc=LIST_NEXT(iteml,next))) iteml = itemc;
|
||||||
|
LIST_INSERT_AFTER(iteml, entry, next);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LIST_INSERT_HEAD(head, entry, next);
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void blob_collection_destroy(struct blob_collection_head *head)
|
||||||
|
{
|
||||||
|
struct blob_item *entry;
|
||||||
|
while ((entry = LIST_FIRST(head)))
|
||||||
|
{
|
||||||
|
LIST_REMOVE(entry, next);
|
||||||
|
free(entry->extra);
|
||||||
|
free(entry->extra2);
|
||||||
|
free(entry->data);
|
||||||
|
free(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool blob_collection_empty(const struct blob_collection_head *head)
|
||||||
|
{
|
||||||
|
return !LIST_FIRST(head);
|
||||||
|
}
|
||||||
|
50
nfq/pools.h
50
nfq/pools.h
@ -12,15 +12,18 @@
|
|||||||
#define HASH_FUNCTION HASH_BER
|
#define HASH_FUNCTION HASH_BER
|
||||||
#include "uthash.h"
|
#include "uthash.h"
|
||||||
|
|
||||||
typedef struct strpool {
|
#define HOSTLIST_POOL_FLAG_STRICT_MATCH 1
|
||||||
char *str; /* key */
|
|
||||||
UT_hash_handle hh; /* makes this structure hashable */
|
|
||||||
} strpool;
|
|
||||||
|
|
||||||
void StrPoolDestroy(strpool **pp);
|
typedef struct hostlist_pool {
|
||||||
bool StrPoolAddStr(strpool **pp,const char *s);
|
char *str; /* key */
|
||||||
bool StrPoolAddStrLen(strpool **pp,const char *s,size_t slen);
|
uint32_t flags; /* custom data */
|
||||||
bool StrPoolCheckStr(strpool *p,const char *s);
|
UT_hash_handle hh; /* makes this structure hashable */
|
||||||
|
} hostlist_pool;
|
||||||
|
|
||||||
|
void HostlistPoolDestroy(hostlist_pool **pp);
|
||||||
|
bool HostlistPoolAddStr(hostlist_pool **pp, const char *s, uint32_t flags);
|
||||||
|
bool HostlistPoolAddStrLen(hostlist_pool **pp, const char *s, size_t slen, uint32_t flags);
|
||||||
|
hostlist_pool *HostlistPoolGetStr(hostlist_pool *p, const char *s);
|
||||||
|
|
||||||
struct str_list {
|
struct str_list {
|
||||||
char *str;
|
char *str;
|
||||||
@ -29,10 +32,10 @@ struct str_list {
|
|||||||
LIST_HEAD(str_list_head, str_list);
|
LIST_HEAD(str_list_head, str_list);
|
||||||
|
|
||||||
typedef struct hostfail_pool {
|
typedef struct hostfail_pool {
|
||||||
char *str; /* key */
|
char *str; /* key */
|
||||||
int counter; /* value */
|
int counter; /* value */
|
||||||
time_t expire; /* when to expire record (unixtime) */
|
time_t expire; /* when to expire record (unixtime) */
|
||||||
UT_hash_handle hh; /* makes this structure hashable */
|
UT_hash_handle hh; /* makes this structure hashable */
|
||||||
} hostfail_pool;
|
} hostfail_pool;
|
||||||
|
|
||||||
void HostFailPoolDestroy(hostfail_pool **pp);
|
void HostFailPoolDestroy(hostfail_pool **pp);
|
||||||
@ -50,8 +53,8 @@ void strlist_destroy(struct str_list_head *head);
|
|||||||
|
|
||||||
struct hostlist_file {
|
struct hostlist_file {
|
||||||
char *filename;
|
char *filename;
|
||||||
time_t mod_time;
|
file_mod_sig mod_sig;
|
||||||
strpool *hostlist;
|
hostlist_pool *hostlist;
|
||||||
LIST_ENTRY(hostlist_file) next;
|
LIST_ENTRY(hostlist_file) next;
|
||||||
};
|
};
|
||||||
LIST_HEAD(hostlist_files_head, hostlist_file);
|
LIST_HEAD(hostlist_files_head, hostlist_file);
|
||||||
@ -59,6 +62,7 @@ LIST_HEAD(hostlist_files_head, hostlist_file);
|
|||||||
struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const char *filename);
|
struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const char *filename);
|
||||||
void hostlist_files_destroy(struct hostlist_files_head *head);
|
void hostlist_files_destroy(struct hostlist_files_head *head);
|
||||||
struct hostlist_file *hostlist_files_search(struct hostlist_files_head *head, const char *filename);
|
struct hostlist_file *hostlist_files_search(struct hostlist_files_head *head, const char *filename);
|
||||||
|
void hostlist_files_reset_modtime(struct hostlist_files_head *list);
|
||||||
|
|
||||||
struct hostlist_item {
|
struct hostlist_item {
|
||||||
struct hostlist_file *hfile;
|
struct hostlist_file *hfile;
|
||||||
@ -111,7 +115,7 @@ void ipsetPrint(ipset *ipset);
|
|||||||
|
|
||||||
struct ipset_file {
|
struct ipset_file {
|
||||||
char *filename;
|
char *filename;
|
||||||
time_t mod_time;
|
file_mod_sig mod_sig;
|
||||||
ipset ipset;
|
ipset ipset;
|
||||||
LIST_ENTRY(ipset_file) next;
|
LIST_ENTRY(ipset_file) next;
|
||||||
};
|
};
|
||||||
@ -120,6 +124,7 @@ LIST_HEAD(ipset_files_head, ipset_file);
|
|||||||
struct ipset_file *ipset_files_add(struct ipset_files_head *head, const char *filename);
|
struct ipset_file *ipset_files_add(struct ipset_files_head *head, const char *filename);
|
||||||
void ipset_files_destroy(struct ipset_files_head *head);
|
void ipset_files_destroy(struct ipset_files_head *head);
|
||||||
struct ipset_file *ipset_files_search(struct ipset_files_head *head, const char *filename);
|
struct ipset_file *ipset_files_search(struct ipset_files_head *head, const char *filename);
|
||||||
|
void ipset_files_reset_modtime(struct ipset_files_head *list);
|
||||||
|
|
||||||
struct ipset_item {
|
struct ipset_item {
|
||||||
struct ipset_file *hfile;
|
struct ipset_file *hfile;
|
||||||
@ -141,3 +146,18 @@ bool port_filter_add(struct port_filters_head *head, const port_filter *pf);
|
|||||||
void port_filters_destroy(struct port_filters_head *head);
|
void port_filters_destroy(struct port_filters_head *head);
|
||||||
bool port_filters_in_range(const struct port_filters_head *head, uint16_t port);
|
bool port_filters_in_range(const struct port_filters_head *head, uint16_t port);
|
||||||
bool port_filters_deny_if_empty(struct port_filters_head *head);
|
bool port_filters_deny_if_empty(struct port_filters_head *head);
|
||||||
|
|
||||||
|
|
||||||
|
struct blob_item {
|
||||||
|
uint8_t *data; // main data blob
|
||||||
|
size_t size; // main data blob size
|
||||||
|
size_t size_buf;// main data blob allocated size
|
||||||
|
void *extra; // any data without size
|
||||||
|
void *extra2; // any data without size
|
||||||
|
LIST_ENTRY(blob_item) next;
|
||||||
|
};
|
||||||
|
LIST_HEAD(blob_collection_head, blob_item);
|
||||||
|
struct blob_item *blob_collection_add(struct blob_collection_head *head);
|
||||||
|
struct blob_item *blob_collection_add_blob(struct blob_collection_head *head, const void *data, size_t size, size_t size_reserve);
|
||||||
|
void blob_collection_destroy(struct blob_collection_head *head);
|
||||||
|
bool blob_collection_empty(const struct blob_collection_head *head);
|
||||||
|
136
nfq/protocol.c
136
nfq/protocol.c
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
#include "params.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@ -33,6 +35,8 @@ const char *l7proto_str(t_l7proto l7)
|
|||||||
case QUIC: return "quic";
|
case QUIC: return "quic";
|
||||||
case WIREGUARD: return "wireguard";
|
case WIREGUARD: return "wireguard";
|
||||||
case DHT: return "dht";
|
case DHT: return "dht";
|
||||||
|
case DISCORD: return "discord";
|
||||||
|
case STUN: return "stun";
|
||||||
default: return "unknown";
|
default: return "unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,7 +47,9 @@ bool l7_proto_match(t_l7proto l7proto, uint32_t filter_l7)
|
|||||||
(l7proto==TLS && (filter_l7 & L7_PROTO_TLS)) ||
|
(l7proto==TLS && (filter_l7 & L7_PROTO_TLS)) ||
|
||||||
(l7proto==QUIC && (filter_l7 & L7_PROTO_QUIC)) ||
|
(l7proto==QUIC && (filter_l7 & L7_PROTO_QUIC)) ||
|
||||||
(l7proto==WIREGUARD && (filter_l7 & L7_PROTO_WIREGUARD)) ||
|
(l7proto==WIREGUARD && (filter_l7 & L7_PROTO_WIREGUARD)) ||
|
||||||
(l7proto==DHT && (filter_l7 & L7_PROTO_DHT));
|
(l7proto==DHT && (filter_l7 & L7_PROTO_DHT)) ||
|
||||||
|
(l7proto==DISCORD && (filter_l7 & L7_PROTO_DISCORD)) ||
|
||||||
|
(l7proto==STUN && (filter_l7 & L7_PROTO_STUN));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PM_ABS 0
|
#define PM_ABS 0
|
||||||
@ -151,7 +157,7 @@ void ResolveMultiPos(const uint8_t *data, size_t sz, t_l7proto l7proto, const st
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *http_methods[] = { "GET /","POST /","HEAD /","OPTIONS /","PUT /","DELETE /","CONNECT /","TRACE /",NULL };
|
const char *http_methods[] = { "GET /","POST /","HEAD /","OPTIONS ","PUT /","DELETE /","CONNECT ","TRACE /",NULL };
|
||||||
const char *HttpMethod(const uint8_t *data, size_t len)
|
const char *HttpMethod(const uint8_t *data, size_t len)
|
||||||
{
|
{
|
||||||
const char **method;
|
const char **method;
|
||||||
@ -339,6 +345,19 @@ size_t HttpPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size_t sz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *TLSVersionStr(uint16_t tlsver)
|
||||||
|
{
|
||||||
|
switch(tlsver)
|
||||||
|
{
|
||||||
|
case 0x0301: return "TLS 1.0";
|
||||||
|
case 0x0302: return "TLS 1.1";
|
||||||
|
case 0x0303: return "TLS 1.2";
|
||||||
|
case 0x0304: return "TLS 1.3";
|
||||||
|
default:
|
||||||
|
// 0x0a0a, 0x1a1a, ..., 0xfafa
|
||||||
|
return (((tlsver & 0x0F0F) == 0x0A0A) && ((tlsver>>12)==((tlsver>>4)&0xF))) ? "GREASE" : "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t TLSRecordDataLen(const uint8_t *data)
|
uint16_t TLSRecordDataLen(const uint8_t *data)
|
||||||
{
|
{
|
||||||
@ -371,6 +390,46 @@ bool IsTLSHandshakeFull(const uint8_t *data, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool TLSFindExtLenOffsetInHandshake(const uint8_t *data, size_t len, size_t *off)
|
||||||
|
{
|
||||||
|
// +0
|
||||||
|
// u8 HandshakeType: ClientHello
|
||||||
|
// u24 Length
|
||||||
|
// u16 Version
|
||||||
|
// c[32] random
|
||||||
|
// u8 SessionIDLength
|
||||||
|
// <SessionID>
|
||||||
|
// u16 CipherSuitesLength
|
||||||
|
// <CipherSuites>
|
||||||
|
// u8 CompressionMethodsLength
|
||||||
|
// <CompressionMethods>
|
||||||
|
// u16 ExtensionsLength
|
||||||
|
|
||||||
|
size_t l;
|
||||||
|
|
||||||
|
l = 1 + 3 + 2 + 32;
|
||||||
|
// SessionIDLength
|
||||||
|
if (len < (l + 1)) return false;
|
||||||
|
l += data[l] + 1;
|
||||||
|
// CipherSuitesLength
|
||||||
|
if (len < (l + 2)) return false;
|
||||||
|
l += pntoh16(data + l) + 2;
|
||||||
|
// CompressionMethodsLength
|
||||||
|
if (len < (l + 1)) return false;
|
||||||
|
l += data[l] + 1;
|
||||||
|
// ExtensionsLength
|
||||||
|
if (len < (l + 2)) return false;
|
||||||
|
*off = l;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool TLSFindExtLen(const uint8_t *data, size_t len, size_t *off)
|
||||||
|
{
|
||||||
|
if (!TLSFindExtLenOffsetInHandshake(data+5,len-5,off))
|
||||||
|
return false;
|
||||||
|
*off+=5;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// bPartialIsOK=true - accept partial packets not containing the whole TLS message
|
// bPartialIsOK=true - accept partial packets not containing the whole TLS message
|
||||||
bool TLSFindExtInHandshake(const uint8_t *data, size_t len, uint16_t type, const uint8_t **ext, size_t *len_ext, bool bPartialIsOK)
|
bool TLSFindExtInHandshake(const uint8_t *data, size_t len, uint16_t type, const uint8_t **ext, size_t *len_ext, bool bPartialIsOK)
|
||||||
{
|
{
|
||||||
@ -391,18 +450,7 @@ bool TLSFindExtInHandshake(const uint8_t *data, size_t len, uint16_t type, const
|
|||||||
|
|
||||||
if (!bPartialIsOK && !IsTLSHandshakeFull(data,len)) return false;
|
if (!bPartialIsOK && !IsTLSHandshakeFull(data,len)) return false;
|
||||||
|
|
||||||
l = 1 + 3 + 2 + 32;
|
if (!TLSFindExtLenOffsetInHandshake(data,len,&l)) return false;
|
||||||
// SessionIDLength
|
|
||||||
if (len < (l + 1)) return false;
|
|
||||||
l += data[l] + 1;
|
|
||||||
// CipherSuitesLength
|
|
||||||
if (len < (l + 2)) return false;
|
|
||||||
l += pntoh16(data + l) + 2;
|
|
||||||
// CompressionMethodsLength
|
|
||||||
if (len < (l + 1)) return false;
|
|
||||||
l += data[l] + 1;
|
|
||||||
// ExtensionsLength
|
|
||||||
if (len < (l + 2)) return false;
|
|
||||||
|
|
||||||
data += l; len -= l;
|
data += l; len -= l;
|
||||||
l = pntoh16(data);
|
l = pntoh16(data);
|
||||||
@ -449,7 +497,7 @@ bool TLSFindExt(const uint8_t *data, size_t len, uint16_t type, const uint8_t **
|
|||||||
if (reclen<len) len=reclen; // correct len if it has more data than the first tls record has
|
if (reclen<len) len=reclen; // correct len if it has more data than the first tls record has
|
||||||
return TLSFindExtInHandshake(data + 5, len - 5, type, ext, len_ext, bPartialIsOK);
|
return TLSFindExtInHandshake(data + 5, len - 5, type, ext, len_ext, bPartialIsOK);
|
||||||
}
|
}
|
||||||
static bool TLSAdvanceToHostInSNI(const uint8_t **ext, size_t *elen, size_t *slen)
|
bool TLSAdvanceToHostInSNI(const uint8_t **ext, size_t *elen, size_t *slen)
|
||||||
{
|
{
|
||||||
// u16 data+0 - name list length
|
// u16 data+0 - name list length
|
||||||
// u8 data+2 - server name type. 0=host_name
|
// u8 data+2 - server name type. 0=host_name
|
||||||
@ -507,7 +555,7 @@ size_t TLSPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size_t sz)
|
|||||||
case PM_HOST_MIDSLD:
|
case PM_HOST_MIDSLD:
|
||||||
case PM_HOST_ENDSLD:
|
case PM_HOST_ENDSLD:
|
||||||
case PM_SNI_EXT:
|
case PM_SNI_EXT:
|
||||||
if (TLSFindExt(data,sz,0,&ext,&elen,false))
|
if (TLSFindExt(data,sz,0,&ext,&elen,TLS_PARTIALS_ENABLE))
|
||||||
{
|
{
|
||||||
if (posmarker==PM_SNI_EXT)
|
if (posmarker==PM_SNI_EXT)
|
||||||
{
|
{
|
||||||
@ -813,7 +861,16 @@ bool QUICDecryptInitial(const uint8_t *data, size_t data_len, uint8_t *clean, si
|
|||||||
return !memcmp(data + pn_offset + pkn_len + cryptlen, atag, 16);
|
return !memcmp(data + pn_offset + pkn_len + cryptlen, atag, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,size_t *defrag_len)
|
struct range64
|
||||||
|
{
|
||||||
|
uint64_t offset,len;
|
||||||
|
};
|
||||||
|
#define MAX_DEFRAG_PIECES 128
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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
|
||||||
// chromium randomly splits it and pads with zero/one bytes to force support the standard
|
// chromium randomly splits it and pads with zero/one bytes to force support the standard
|
||||||
@ -822,13 +879,15 @@ bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,siz
|
|||||||
if (*defrag_len<10) return false;
|
if (*defrag_len<10) return false;
|
||||||
uint8_t *defrag_data = defrag+10;
|
uint8_t *defrag_data = defrag+10;
|
||||||
size_t defrag_data_len = *defrag_len-10;
|
size_t defrag_data_len = *defrag_len-10;
|
||||||
|
|
||||||
uint8_t ft;
|
uint8_t ft;
|
||||||
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];
|
||||||
|
int i,range=0;
|
||||||
|
|
||||||
while(pos<clean_len)
|
while(pos<clean_len)
|
||||||
{
|
{
|
||||||
|
// frame type
|
||||||
ft = clean[pos];
|
ft = clean[pos];
|
||||||
pos++;
|
pos++;
|
||||||
if (ft>1) // 00 - padding, 01 - ping
|
if (ft>1) // 00 - padding, 01 - ping
|
||||||
@ -836,6 +895,7 @@ bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,siz
|
|||||||
if (ft!=6) return false; // dont want to know all possible frame type formats
|
if (ft!=6) return false; // dont want to know all possible frame type formats
|
||||||
|
|
||||||
if (pos>=clean_len) return false;
|
if (pos>=clean_len) return false;
|
||||||
|
if (range>=MAX_DEFRAG_PIECES) return false;
|
||||||
|
|
||||||
if ((pos+tvb_get_size(clean[pos])>=clean_len)) return false;
|
if ((pos+tvb_get_size(clean[pos])>=clean_len)) return false;
|
||||||
pos += tvb_get_varint(clean+pos, &offset);
|
pos += tvb_get_varint(clean+pos, &offset);
|
||||||
@ -844,7 +904,7 @@ bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,siz
|
|||||||
pos += tvb_get_varint(clean+pos, &sz);
|
pos += tvb_get_varint(clean+pos, &sz);
|
||||||
if ((pos+sz)>clean_len) return false;
|
if ((pos+sz)>clean_len) return false;
|
||||||
|
|
||||||
if ((offset+sz)>defrag_data_len) return false;
|
if ((offset+sz)>defrag_data_len) return false; // defrag buf overflow
|
||||||
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);
|
||||||
@ -855,6 +915,10 @@ bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,siz
|
|||||||
|
|
||||||
found=true;
|
found=true;
|
||||||
pos+=sz;
|
pos+=sz;
|
||||||
|
|
||||||
|
ranges[range].offset = offset;
|
||||||
|
ranges[range].len = sz;
|
||||||
|
range++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (found)
|
if (found)
|
||||||
@ -866,6 +930,23 @@ bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,siz
|
|||||||
phton64(defrag+2,szmax);
|
phton64(defrag+2,szmax);
|
||||||
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);
|
||||||
|
|
||||||
|
//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);
|
||||||
}
|
}
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
@ -936,9 +1017,24 @@ bool IsQUICInitial(const uint8_t *data, size_t len)
|
|||||||
|
|
||||||
bool IsWireguardHandshakeInitiation(const uint8_t *data, size_t len)
|
bool IsWireguardHandshakeInitiation(const uint8_t *data, size_t len)
|
||||||
{
|
{
|
||||||
return len==148 && data[0]==1 && data[1]==0 && data[2]==0 && data[3]==0;
|
return len==148 && data[0]==1;
|
||||||
}
|
}
|
||||||
bool IsDhtD1(const uint8_t *data, size_t len)
|
bool IsDhtD1(const uint8_t *data, size_t len)
|
||||||
{
|
{
|
||||||
return len>=7 && data[0]=='d' && data[1]=='1' && data[len-1]=='e';
|
return len>=7 && data[0]=='d' && data[1]=='1' && data[len-1]=='e';
|
||||||
}
|
}
|
||||||
|
bool IsDiscordIpDiscoveryRequest(const uint8_t *data, size_t len)
|
||||||
|
{
|
||||||
|
return len==74 &&
|
||||||
|
data[0]==0 && data[1]==1 &&
|
||||||
|
data[2]==0 && data[3]==70 &&
|
||||||
|
data[8]==0 && memcmp(&data[8],&data[9],63)==0; // address is not set in requests
|
||||||
|
}
|
||||||
|
bool IsStunMessage(const uint8_t *data, size_t len)
|
||||||
|
{
|
||||||
|
return len>=20 && // header size
|
||||||
|
(data[0]&0xC0)==0 && // 2 most significant bits must be zeroes
|
||||||
|
(data[3]&0b11)==0 && // length must be a multiple of 4
|
||||||
|
ntohl(*(uint32_t*)(&data[4]))==0x2112A442 && // magic cookie
|
||||||
|
ntohs(*(uint16_t*)(&data[2]))==len-20;
|
||||||
|
}
|
||||||
|
@ -7,12 +7,14 @@
|
|||||||
#include "crypto/aes-gcm.h"
|
#include "crypto/aes-gcm.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|
||||||
typedef enum {UNKNOWN=0, HTTP, TLS, QUIC, WIREGUARD, DHT} t_l7proto;
|
typedef enum {UNKNOWN=0, HTTP, TLS, QUIC, WIREGUARD, DHT, DISCORD, STUN} t_l7proto;
|
||||||
#define L7_PROTO_HTTP 0x00000001
|
#define L7_PROTO_HTTP 0x00000001
|
||||||
#define L7_PROTO_TLS 0x00000002
|
#define L7_PROTO_TLS 0x00000002
|
||||||
#define L7_PROTO_QUIC 0x00000004
|
#define L7_PROTO_QUIC 0x00000004
|
||||||
#define L7_PROTO_WIREGUARD 0x00000008
|
#define L7_PROTO_WIREGUARD 0x00000008
|
||||||
#define L7_PROTO_DHT 0x00000010
|
#define L7_PROTO_DHT 0x00000010
|
||||||
|
#define L7_PROTO_DISCORD 0x00000020
|
||||||
|
#define L7_PROTO_STUN 0x00000040
|
||||||
#define L7_PROTO_UNKNOWN 0x80000000
|
#define L7_PROTO_UNKNOWN 0x80000000
|
||||||
const char *l7proto_str(t_l7proto l7);
|
const char *l7proto_str(t_l7proto l7);
|
||||||
bool l7_proto_match(t_l7proto l7proto, uint32_t filter_l7);
|
bool l7_proto_match(t_l7proto l7proto, uint32_t filter_l7);
|
||||||
@ -55,6 +57,7 @@ int HttpReplyCode(const uint8_t *data, size_t len);
|
|||||||
// 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);
|
||||||
|
|
||||||
|
const char *TLSVersionStr(uint16_t tlsver);
|
||||||
uint16_t TLSRecordDataLen(const uint8_t *data);
|
uint16_t TLSRecordDataLen(const uint8_t *data);
|
||||||
size_t TLSRecordLen(const uint8_t *data);
|
size_t TLSRecordLen(const uint8_t *data);
|
||||||
bool IsTLSRecordFull(const uint8_t *data, size_t len);
|
bool IsTLSRecordFull(const uint8_t *data, size_t len);
|
||||||
@ -62,6 +65,9 @@ bool IsTLSClientHello(const uint8_t *data, size_t len, bool bPartialIsOK);
|
|||||||
size_t TLSHandshakeLen(const uint8_t *data);
|
size_t TLSHandshakeLen(const uint8_t *data);
|
||||||
bool IsTLSHandshakeClientHello(const uint8_t *data, size_t len);
|
bool IsTLSHandshakeClientHello(const uint8_t *data, size_t len);
|
||||||
bool IsTLSHandshakeFull(const uint8_t *data, size_t len);
|
bool IsTLSHandshakeFull(const uint8_t *data, size_t len);
|
||||||
|
bool TLSAdvanceToHostInSNI(const uint8_t **ext, size_t *elen, size_t *slen);
|
||||||
|
bool TLSFindExtLen(const uint8_t *data, size_t len, size_t *off);
|
||||||
|
bool TLSFindExtLenOffsetInHandshake(const uint8_t *data, size_t len, size_t *off);
|
||||||
bool TLSFindExt(const uint8_t *data, size_t len, uint16_t type, const uint8_t **ext, size_t *len_ext, bool bPartialIsOK);
|
bool TLSFindExt(const uint8_t *data, size_t len, uint16_t type, const uint8_t **ext, size_t *len_ext, bool bPartialIsOK);
|
||||||
bool TLSFindExtInHandshake(const uint8_t *data, size_t len, uint16_t type, const uint8_t **ext, size_t *len_ext, bool bPartialIsOK);
|
bool TLSFindExtInHandshake(const uint8_t *data, size_t len, uint16_t type, const uint8_t **ext, size_t *len_ext, bool bPartialIsOK);
|
||||||
bool TLSHelloExtractHost(const uint8_t *data, size_t len, char *host, size_t len_host, bool bPartialIsOK);
|
bool TLSHelloExtractHost(const uint8_t *data, size_t len, char *host, size_t len_host, bool bPartialIsOK);
|
||||||
@ -69,6 +75,8 @@ bool TLSHelloExtractHostFromHandshake(const uint8_t *data, size_t len, char *hos
|
|||||||
|
|
||||||
bool IsWireguardHandshakeInitiation(const uint8_t *data, size_t len);
|
bool IsWireguardHandshakeInitiation(const uint8_t *data, size_t len);
|
||||||
bool IsDhtD1(const uint8_t *data, size_t len);
|
bool IsDhtD1(const uint8_t *data, size_t len);
|
||||||
|
bool IsDiscordIpDiscoveryRequest(const uint8_t *data, size_t len);
|
||||||
|
bool IsStunMessage(const uint8_t *data, size_t len);
|
||||||
|
|
||||||
#define QUIC_MAX_CID_LENGTH 20
|
#define QUIC_MAX_CID_LENGTH 20
|
||||||
typedef struct quic_cid {
|
typedef struct quic_cid {
|
||||||
@ -84,5 +92,6 @@ uint8_t QUICDraftVersion(uint32_t version);
|
|||||||
bool QUICExtractDCID(const uint8_t *data, size_t len, quic_cid_t *cid);
|
bool QUICExtractDCID(const uint8_t *data, size_t len, quic_cid_t *cid);
|
||||||
|
|
||||||
bool QUICDecryptInitial(const uint8_t *data, size_t data_len, uint8_t *clean, size_t *clean_len);
|
bool QUICDecryptInitial(const uint8_t *data, size_t data_len, uint8_t *clean, size_t *clean_len);
|
||||||
bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,size_t *defrag_len);
|
// returns true if crypto frames were found . bFull = true if crypto frame fragments have full coverage
|
||||||
|
bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,size_t *defrag_len, bool *bFull);
|
||||||
//bool QUICExtractHostFromInitial(const uint8_t *data, size_t data_len, char *host, size_t len_host, bool *bDecryptOK, bool *bIsCryptoHello);
|
//bool QUICExtractHostFromInitial(const uint8_t *data, size_t data_len, char *host, size_t len_host, bool *bDecryptOK, bool *bIsCryptoHello);
|
||||||
|
10
nfq/sec.c
10
nfq/sec.c
@ -88,10 +88,6 @@ SYS_symlinkat,
|
|||||||
SYS_link,
|
SYS_link,
|
||||||
#endif
|
#endif
|
||||||
SYS_linkat,
|
SYS_linkat,
|
||||||
#ifdef SYS_pkey_mprotect
|
|
||||||
SYS_pkey_mprotect,
|
|
||||||
#endif
|
|
||||||
SYS_mprotect,
|
|
||||||
SYS_truncate,
|
SYS_truncate,
|
||||||
#ifdef SYS_truncate64
|
#ifdef SYS_truncate64
|
||||||
SYS_truncate64,
|
SYS_truncate64,
|
||||||
@ -291,7 +287,7 @@ bool can_drop_root(void)
|
|||||||
{
|
{
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
// has some caps
|
// has some caps
|
||||||
return checkpcap((1<<CAP_SETUID)|(1<<CAP_SETGID)|(1<<CAP_SETPCAP));
|
return checkpcap((1<<CAP_SETUID)|(1<<CAP_SETGID));
|
||||||
#else
|
#else
|
||||||
// effective root
|
// effective root
|
||||||
return !geteuid();
|
return !geteuid();
|
||||||
@ -323,11 +319,7 @@ bool droproot(uid_t uid, gid_t gid)
|
|||||||
DLOG_PERROR("setuid");
|
DLOG_PERROR("setuid");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#ifdef __linux__
|
|
||||||
return dropcaps();
|
|
||||||
#else
|
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_id(void)
|
void print_id(void)
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
CC ?= cc
|
CC ?= cc
|
||||||
CFLAGS += -std=gnu99 -s -Os
|
CFLAGS += -std=gnu99 -s -Os -flto=auto
|
||||||
LIBS = -lz -lpthread
|
LIBS = -lz -lpthread
|
||||||
SRC_FILES = *.c
|
SRC_FILES = *.c
|
||||||
|
|
||||||
all: tpws
|
all: tpws
|
||||||
|
|
||||||
tpws: $(SRC_FILES)
|
tpws: $(SRC_FILES)
|
||||||
$(CC) $(CFLAGS) -Iepoll-shim/include -o tpws $(SRC_FILES) epoll-shim/src/*.c $(LDFLAGS) $(LIBS)
|
$(CC) $(CFLAGS) -Iepoll-shim/include -o tpws $(SRC_FILES) epoll-shim/src/*.c $(LIBS) $(LDFLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f tpws *.o
|
rm -f tpws *.o
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
CFLAGS += -std=gnu99 -Os
|
CFLAGS += -std=gnu99 -Os -flto=auto
|
||||||
|
CFLAGS_SYSTEMD = -DUSE_SYSTEMD
|
||||||
CFLAGS_BSD = -Wno-address-of-packed-member
|
CFLAGS_BSD = -Wno-address-of-packed-member
|
||||||
LIBS = -lz -lpthread
|
LIBS = -lz -lpthread
|
||||||
|
LIBS_SYSTEMD = -lsystemd
|
||||||
LIBS_ANDROID = -lz
|
LIBS_ANDROID = -lz
|
||||||
SRC_FILES = *.c
|
SRC_FILES = *.c
|
||||||
SRC_FILES_ANDROID = $(SRC_FILES) andr/*.c
|
SRC_FILES_ANDROID = $(SRC_FILES) andr/*.c
|
||||||
@ -9,17 +11,20 @@ SRC_FILES_ANDROID = $(SRC_FILES) andr/*.c
|
|||||||
all: tpws
|
all: tpws
|
||||||
|
|
||||||
tpws: $(SRC_FILES)
|
tpws: $(SRC_FILES)
|
||||||
$(CC) -s $(CFLAGS) -o tpws $(SRC_FILES) $(LDFLAGS) $(LIBS)
|
$(CC) -s $(CFLAGS) -o tpws $(SRC_FILES) $(LIBS) $(LDFLAGS)
|
||||||
|
|
||||||
|
systemd: $(SRC_FILES)
|
||||||
|
$(CC) -s $(CFLAGS) $(CFLAGS_SYSTEMD) -o tpws $(SRC_FILES) $(LIBS) $(LIBS_SYSTEMD) $(LDFLAGS)
|
||||||
|
|
||||||
android: $(SRC_FILES)
|
android: $(SRC_FILES)
|
||||||
$(CC) -s $(CFLAGS) -o tpws $(SRC_FILES_ANDROID) $(LDFLAGS) $(LIBS_ANDROID)
|
$(CC) -s $(CFLAGS) -o tpws $(SRC_FILES_ANDROID) $(LIBS_ANDROID) $(LDFLAGS)
|
||||||
|
|
||||||
bsd: $(SRC_FILES)
|
bsd: $(SRC_FILES)
|
||||||
$(CC) -s $(CFLAGS) $(CFLAGS_BSD) -Iepoll-shim/include -o tpws $(SRC_FILES) epoll-shim/src/*.c $(LDFLAGS) $(LIBS)
|
$(CC) -s $(CFLAGS) $(CFLAGS_BSD) -Iepoll-shim/include -o tpws $(SRC_FILES) epoll-shim/src/*.c $(LIBS) $(LDFLAGS)
|
||||||
|
|
||||||
mac: $(SRC_FILES)
|
mac: $(SRC_FILES)
|
||||||
$(CC) $(CFLAGS) $(CFLAGS_BSD) -Iepoll-shim/include -Imacos -o tpwsa -target arm64-apple-macos10.8 $(SRC_FILES) epoll-shim/src/*.c $(LDFLAGS) $(LIBS)
|
$(CC) $(CFLAGS) $(CFLAGS_BSD) -Iepoll-shim/include -Imacos -o tpwsa -target arm64-apple-macos10.8 $(SRC_FILES) epoll-shim/src/*.c $(LIBS) $(LDFLAGS)
|
||||||
$(CC) $(CFLAGS) $(CFLAGS_BSD) -Iepoll-shim/include -Imacos -o tpwsx -target x86_64-apple-macos10.8 $(SRC_FILES) epoll-shim/src/*.c $(LDFLAGS) $(LIBS)
|
$(CC) $(CFLAGS) $(CFLAGS_BSD) -Iepoll-shim/include -Imacos -o tpwsx -target x86_64-apple-macos10.8 $(SRC_FILES) epoll-shim/src/*.c $(LIBS) $(LDFLAGS)
|
||||||
strip tpwsa tpwsx
|
strip tpwsa tpwsx
|
||||||
lipo -create -output tpws tpwsx tpwsa
|
lipo -create -output tpws tpwsx tpwsa
|
||||||
rm -f tpwsx tpwsa
|
rm -f tpwsx tpwsa
|
||||||
|
@ -65,11 +65,8 @@ int z_readfile(FILE *F, char **buf, size_t *size)
|
|||||||
|
|
||||||
zerr:
|
zerr:
|
||||||
inflateEnd(&zs);
|
inflateEnd(&zs);
|
||||||
if (*buf)
|
free(*buf);
|
||||||
{
|
*buf = NULL;
|
||||||
free(*buf);
|
|
||||||
*buf = NULL;
|
|
||||||
}
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,10 +11,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#ifdef __linux__
|
|
||||||
#include <linux/tcp.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
#include "andr/ifaddrs.h"
|
#include "andr/ifaddrs.h"
|
||||||
@ -23,6 +20,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <linux/tcp.h>
|
||||||
|
#endif
|
||||||
|
#include "linux_compat.h"
|
||||||
|
|
||||||
int unique_size_t(size_t *pu, int ct)
|
int unique_size_t(size_t *pu, int ct)
|
||||||
{
|
{
|
||||||
@ -77,6 +78,13 @@ char *strncasestr(const char *s, const char *find, size_t slen)
|
|||||||
return (char *)s;
|
return (char *)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool str_ends_with(const char *s, const char *suffix)
|
||||||
|
{
|
||||||
|
size_t slen = strlen(s);
|
||||||
|
size_t suffix_len = strlen(suffix);
|
||||||
|
return suffix_len <= slen && !strcmp(s + slen - suffix_len, suffix);
|
||||||
|
}
|
||||||
|
|
||||||
bool load_file(const char *filename, void *buffer, size_t *buffer_size)
|
bool load_file(const char *filename, void *buffer, size_t *buffer_size)
|
||||||
{
|
{
|
||||||
FILE *F;
|
FILE *F;
|
||||||
@ -314,6 +322,29 @@ time_t file_mod_time(const char *filename)
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
return stat(filename, &st) == -1 ? 0 : st.st_mtime;
|
return stat(filename, &st) == -1 ? 0 : st.st_mtime;
|
||||||
}
|
}
|
||||||
|
bool file_mod_signature(const char *filename, file_mod_sig *ms)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
if (stat(filename,&st)==-1)
|
||||||
|
{
|
||||||
|
FILE_MOD_RESET(ms);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ms->mod_time=st.st_mtime;
|
||||||
|
ms->size=st.st_size;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool file_open_test(const char *filename, int flags)
|
||||||
|
{
|
||||||
|
int fd = open(filename,flags);
|
||||||
|
if (fd>=0)
|
||||||
|
{
|
||||||
|
close(fd);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool pf_in_range(uint16_t port, const port_filter *pf)
|
bool pf_in_range(uint16_t port, const port_filter *pf)
|
||||||
{
|
{
|
||||||
@ -359,6 +390,11 @@ bool pf_is_empty(const port_filter *pf)
|
|||||||
return !pf->neg && !pf->from && !pf->to;
|
return !pf->neg && !pf->from && !pf->to;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_console_io_buffering(void)
|
||||||
|
{
|
||||||
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
|
setvbuf(stderr, NULL, _IOLBF, 0);
|
||||||
|
}
|
||||||
|
|
||||||
bool set_env_exedir(const char *argv0)
|
bool set_env_exedir(const char *argv0)
|
||||||
{
|
{
|
||||||
@ -481,7 +517,7 @@ void msleep(unsigned int ms)
|
|||||||
bool socket_supports_notsent()
|
bool socket_supports_notsent()
|
||||||
{
|
{
|
||||||
int sfd;
|
int sfd;
|
||||||
struct tcp_info tcpi;
|
struct tcp_info_new tcpi;
|
||||||
|
|
||||||
sfd = socket(AF_INET,SOCK_STREAM,0);
|
sfd = socket(AF_INET,SOCK_STREAM,0);
|
||||||
if (sfd<0) return false;
|
if (sfd<0) return false;
|
||||||
@ -494,11 +530,11 @@ bool socket_supports_notsent()
|
|||||||
}
|
}
|
||||||
close(sfd);
|
close(sfd);
|
||||||
|
|
||||||
return ts>=((char *)&tcpi.tcpi_notsent_bytes - (char *)&tcpi.tcpi_state + sizeof(tcpi.tcpi_notsent_bytes));
|
return ts>=((char *)&tcpi.tcpi_notsent_bytes - (char *)&tcpi + sizeof(tcpi.tcpi_notsent_bytes));
|
||||||
}
|
}
|
||||||
bool socket_has_notsent(int sfd)
|
bool socket_has_notsent(int sfd)
|
||||||
{
|
{
|
||||||
struct tcp_info tcpi;
|
struct tcp_info_new tcpi;
|
||||||
socklen_t ts = sizeof(tcpi);
|
socklen_t ts = sizeof(tcpi);
|
||||||
|
|
||||||
if (getsockopt(sfd, IPPROTO_TCP, TCP_INFO, (char *)&tcpi, &ts) < 0)
|
if (getsockopt(sfd, IPPROTO_TCP, TCP_INFO, (char *)&tcpi, &ts) < 0)
|
||||||
@ -536,4 +572,20 @@ bool socket_wait_notsent(int sfd, unsigned int delay_ms, unsigned int *wasted_ms
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int is_wsl(void)
|
||||||
|
{
|
||||||
|
struct utsname buf;
|
||||||
|
if (uname(&buf) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (strcmp(buf.sysname, "Linux") != 0)
|
||||||
|
return 0;
|
||||||
|
if (str_ends_with(buf.release, "microsoft-standard-WSL2"))
|
||||||
|
return 2;
|
||||||
|
if (str_ends_with(buf.release, "-Microsoft"))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
// 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
|
||||||
@ -22,6 +23,8 @@ void rtrim(char *s);
|
|||||||
void replace_char(char *s, char from, char to);
|
void replace_char(char *s, char from, char to);
|
||||||
char *strncasestr(const char *s,const char *find, size_t slen);
|
char *strncasestr(const char *s,const char *find, size_t slen);
|
||||||
|
|
||||||
|
bool str_ends_with(const char *s, const char *suffix);
|
||||||
|
|
||||||
bool load_file(const char *filename,void *buffer,size_t *buffer_size);
|
bool load_file(const char *filename,void *buffer,size_t *buffer_size);
|
||||||
bool append_to_list_file(const char *filename, const char *s);
|
bool append_to_list_file(const char *filename, const char *s);
|
||||||
|
|
||||||
@ -62,7 +65,16 @@ static inline void phton16(uint8_t *p, uint16_t v) {
|
|||||||
|
|
||||||
int fprint_localtime(FILE *F);
|
int fprint_localtime(FILE *F);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
time_t mod_time;
|
||||||
|
off_t size;
|
||||||
|
} file_mod_sig;
|
||||||
|
#define FILE_MOD_COMPARE(ms1,ms2) (((ms1)->mod_time==(ms2)->mod_time) && ((ms1)->size==(ms2)->size))
|
||||||
|
#define FILE_MOD_RESET(ms) memset(ms,0,sizeof(file_mod_sig))
|
||||||
|
bool file_mod_signature(const char *filename, file_mod_sig *ms);
|
||||||
time_t file_mod_time(const char *filename);
|
time_t file_mod_time(const char *filename);
|
||||||
|
bool file_open_test(const char *filename, int flags);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -73,6 +85,7 @@ bool pf_in_range(uint16_t port, const port_filter *pf);
|
|||||||
bool pf_parse(const char *s, port_filter *pf);
|
bool pf_parse(const char *s, port_filter *pf);
|
||||||
bool pf_is_empty(const port_filter *pf);
|
bool pf_is_empty(const port_filter *pf);
|
||||||
|
|
||||||
|
void set_console_io_buffering(void);
|
||||||
bool set_env_exedir(const char *argv0);
|
bool set_env_exedir(const char *argv0);
|
||||||
|
|
||||||
#ifndef IN_LOOPBACK
|
#ifndef IN_LOOPBACK
|
||||||
@ -123,4 +136,6 @@ void msleep(unsigned int ms);
|
|||||||
bool socket_supports_notsent();
|
bool socket_supports_notsent();
|
||||||
bool socket_has_notsent(int sfd);
|
bool socket_has_notsent(int sfd);
|
||||||
bool socket_wait_notsent(int sfd, unsigned int delay_ms, unsigned int *wasted_ms);
|
bool socket_wait_notsent(int sfd, unsigned int delay_ms, unsigned int *wasted_ms);
|
||||||
|
|
||||||
|
int is_wsl();
|
||||||
#endif
|
#endif
|
||||||
|
127
tpws/hostlist.c
127
tpws/hostlist.c
@ -4,7 +4,7 @@
|
|||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|
||||||
// inplace tolower() and add to pool
|
// inplace tolower() and add to pool
|
||||||
static bool addpool(strpool **hostlist, char **s, const char *end, int *ct)
|
static bool addpool(hostlist_pool **hostlist, char **s, const char *end, int *ct)
|
||||||
{
|
{
|
||||||
char *p=*s;
|
char *p=*s;
|
||||||
|
|
||||||
@ -17,14 +17,20 @@ static bool addpool(strpool **hostlist, char **s, const char *end, int *ct)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// advance until eol lowering all chars
|
// advance until eol lowering all chars
|
||||||
for (; p<end && *p && *p!='\r' && *p != '\n'; p++) *p=tolower(*p);
|
uint32_t flags = 0;
|
||||||
if (!StrPoolAddStrLen(hostlist, *s, p-*s))
|
if (*p=='^')
|
||||||
{
|
{
|
||||||
StrPoolDestroy(hostlist);
|
p = ++(*s);
|
||||||
|
flags |= HOSTLIST_POOL_FLAG_STRICT_MATCH;
|
||||||
|
}
|
||||||
|
for (; p<end && *p && *p!='\r' && *p != '\n'; p++) *p=tolower(*p);
|
||||||
|
if (!HostlistPoolAddStrLen(hostlist, *s, p-*s, flags))
|
||||||
|
{
|
||||||
|
HostlistPoolDestroy(hostlist);
|
||||||
*hostlist = NULL;
|
*hostlist = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
(*ct)++;
|
if (ct) (*ct)++;
|
||||||
}
|
}
|
||||||
// advance to the next line
|
// advance to the next line
|
||||||
for (; p<end && (!*p || *p=='\r' || *p=='\n') ; p++);
|
for (; p<end && (!*p || *p=='\r' || *p=='\n') ; p++);
|
||||||
@ -32,7 +38,12 @@ static bool addpool(strpool **hostlist, char **s, const char *end, int *ct)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppendHostList(strpool **hostlist, const char *filename)
|
bool AppendHostlistItem(hostlist_pool **hostlist, char *s)
|
||||||
|
{
|
||||||
|
return addpool(hostlist,&s,s+strlen(s),NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppendHostList(hostlist_pool **hostlist, const char *filename)
|
||||||
{
|
{
|
||||||
char *p, *e, s[256], *zbuf;
|
char *p, *e, s[256], *zbuf;
|
||||||
size_t zsize;
|
size_t zsize;
|
||||||
@ -98,21 +109,25 @@ bool AppendHostList(strpool **hostlist, const char *filename)
|
|||||||
|
|
||||||
static bool LoadHostList(struct hostlist_file *hfile)
|
static bool LoadHostList(struct hostlist_file *hfile)
|
||||||
{
|
{
|
||||||
time_t t = file_mod_time(hfile->filename);
|
if (hfile->filename)
|
||||||
if (!t)
|
|
||||||
{
|
{
|
||||||
// stat() error
|
file_mod_sig fsig;
|
||||||
DLOG_ERR("cannot access hostlist file '%s'. in-memory content remains unchanged.\n",hfile->filename);
|
if (!file_mod_signature(hfile->filename, &fsig))
|
||||||
return true;
|
{
|
||||||
|
// stat() error
|
||||||
|
DLOG_PERROR("file_mod_signature");
|
||||||
|
DLOG_ERR("cannot access hostlist file '%s'. in-memory content remains unchanged.\n",hfile->filename);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (FILE_MOD_COMPARE(&hfile->mod_sig,&fsig)) return true; // up to date
|
||||||
|
HostlistPoolDestroy(&hfile->hostlist);
|
||||||
|
if (!AppendHostList(&hfile->hostlist, hfile->filename))
|
||||||
|
{
|
||||||
|
HostlistPoolDestroy(&hfile->hostlist);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
hfile->mod_sig=fsig;
|
||||||
}
|
}
|
||||||
if (t==hfile->mod_time) return true; // up to date
|
|
||||||
StrPoolDestroy(&hfile->hostlist);
|
|
||||||
if (!AppendHostList(&hfile->hostlist, hfile->filename))
|
|
||||||
{
|
|
||||||
StrPoolDestroy(&hfile->hostlist);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
hfile->mod_time=t;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
static bool LoadHostLists(struct hostlist_files_head *list)
|
static bool LoadHostLists(struct hostlist_files_head *list)
|
||||||
@ -129,10 +144,10 @@ static bool LoadHostLists(struct hostlist_files_head *list)
|
|||||||
return bres;
|
return bres;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NonEmptyHostlist(strpool **hostlist)
|
bool NonEmptyHostlist(hostlist_pool **hostlist)
|
||||||
{
|
{
|
||||||
// add impossible hostname if the list is empty
|
// add impossible hostname if the list is empty
|
||||||
return *hostlist ? true : StrPoolAddStrLen(hostlist, "@&()", 4);
|
return *hostlist ? true : HostlistPoolAddStrLen(hostlist, "@&()", 4, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MakeAutolistsNonEmpty()
|
static void MakeAutolistsNonEmpty()
|
||||||
@ -155,19 +170,34 @@ bool LoadAllHostLists()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool SearchHostList(strpool *hostlist, const char *host)
|
static bool SearchHostList(hostlist_pool *hostlist, const char *host)
|
||||||
{
|
{
|
||||||
if (hostlist)
|
if (hostlist)
|
||||||
{
|
{
|
||||||
const char *p = host;
|
const char *p = host;
|
||||||
bool bInHostList;
|
const struct hostlist_pool *hp;
|
||||||
|
bool bHostFull=true;
|
||||||
while (p)
|
while (p)
|
||||||
{
|
{
|
||||||
bInHostList = StrPoolCheckStr(hostlist, p);
|
VPRINT("hostlist check for %s : ", p);
|
||||||
VPRINT("hostlist check for %s : %s\n", p, bInHostList ? "positive" : "negative");
|
hp = HostlistPoolGetStr(hostlist, p);
|
||||||
if (bInHostList) return true;
|
if (hp)
|
||||||
|
{
|
||||||
|
if ((hp->flags & HOSTLIST_POOL_FLAG_STRICT_MATCH) && !bHostFull)
|
||||||
|
{
|
||||||
|
VPRINT("negative : strict_mismatch : %s != %s\n", p, host);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VPRINT("positive\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
VPRINT("negative\n");
|
||||||
p = strchr(p, '.');
|
p = strchr(p, '.');
|
||||||
if (p) p++;
|
if (p) p++;
|
||||||
|
bHostFull = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -202,7 +232,7 @@ static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, con
|
|||||||
|
|
||||||
LIST_FOREACH(item, hostlists_exclude, next)
|
LIST_FOREACH(item, hostlists_exclude, next)
|
||||||
{
|
{
|
||||||
VPRINT("[%s] exclude ", item->hfile->filename);
|
VPRINT("[%s] exclude ", item->hfile->filename ? item->hfile->filename : "fixed");
|
||||||
if (SearchHostList(item->hfile->hostlist, host))
|
if (SearchHostList(item->hfile->hostlist, host))
|
||||||
{
|
{
|
||||||
if (excluded) *excluded = true;
|
if (excluded) *excluded = true;
|
||||||
@ -214,7 +244,7 @@ static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, con
|
|||||||
{
|
{
|
||||||
LIST_FOREACH(item, hostlists, next)
|
LIST_FOREACH(item, hostlists, next)
|
||||||
{
|
{
|
||||||
VPRINT("[%s] include ", item->hfile->filename);
|
VPRINT("[%s] include ", item->hfile->filename ? item->hfile->filename : "fixed");
|
||||||
if (SearchHostList(item->hfile->hostlist, host))
|
if (SearchHostList(item->hfile->hostlist, host))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -235,17 +265,29 @@ bool HostlistCheck(const struct desync_profile *dp, const char *host, bool *excl
|
|||||||
static struct hostlist_file *RegisterHostlist_(struct hostlist_files_head *hostlists, struct hostlist_collection_head *hl_collection, const char *filename)
|
static struct hostlist_file *RegisterHostlist_(struct hostlist_files_head *hostlists, struct hostlist_collection_head *hl_collection, const char *filename)
|
||||||
{
|
{
|
||||||
struct hostlist_file *hfile;
|
struct hostlist_file *hfile;
|
||||||
if (!(hfile=hostlist_files_search(hostlists, filename)))
|
|
||||||
if (!(hfile=hostlist_files_add(hostlists, filename)))
|
if (filename)
|
||||||
|
{
|
||||||
|
if (!(hfile=hostlist_files_search(hostlists, filename)))
|
||||||
|
if (!(hfile=hostlist_files_add(hostlists, filename)))
|
||||||
|
return NULL;
|
||||||
|
if (!hostlist_collection_search(hl_collection, filename))
|
||||||
|
if (!hostlist_collection_add(hl_collection, hfile))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(hfile=hostlist_files_add(hostlists, NULL)))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!hostlist_collection_search(hl_collection, filename))
|
|
||||||
if (!hostlist_collection_add(hl_collection, hfile))
|
if (!hostlist_collection_add(hl_collection, hfile))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return hfile;
|
return hfile;
|
||||||
}
|
}
|
||||||
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename)
|
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename)
|
||||||
{
|
{
|
||||||
if (!file_mod_time(filename))
|
if (filename && !file_mod_time(filename))
|
||||||
{
|
{
|
||||||
DLOG_ERR("cannot access hostlist file '%s'\n",filename);
|
DLOG_ERR("cannot access hostlist file '%s'\n",filename);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -265,15 +307,30 @@ void HostlistsDebug()
|
|||||||
struct hostlist_item *hl_item;
|
struct hostlist_item *hl_item;
|
||||||
|
|
||||||
LIST_FOREACH(hfile, ¶ms.hostlists, next)
|
LIST_FOREACH(hfile, ¶ms.hostlists, next)
|
||||||
VPRINT("hostlist file %s%s\n",hfile->filename,hfile->hostlist ? "" : " (empty)");
|
{
|
||||||
|
if (hfile->filename)
|
||||||
|
VPRINT("hostlist file %s%s\n",hfile->filename,hfile->hostlist ? "" : " (empty)");
|
||||||
|
else
|
||||||
|
VPRINT("hostlist fixed%s\n",hfile->hostlist ? "" : " (empty)");
|
||||||
|
}
|
||||||
|
|
||||||
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
||||||
{
|
{
|
||||||
LIST_FOREACH(hl_item, &dpl->dp.hl_collection, next)
|
LIST_FOREACH(hl_item, &dpl->dp.hl_collection, next)
|
||||||
if (hl_item->hfile!=dpl->dp.hostlist_auto)
|
if (hl_item->hfile!=dpl->dp.hostlist_auto)
|
||||||
VPRINT("profile %d include hostlist %s%s\n",dpl->dp.n, hl_item->hfile->filename,hl_item->hfile->hostlist ? "" : " (empty)");
|
{
|
||||||
|
if (hl_item->hfile->filename)
|
||||||
|
VPRINT("profile %d include hostlist %s%s\n",dpl->dp.n, hl_item->hfile->filename,hl_item->hfile->hostlist ? "" : " (empty)");
|
||||||
|
else
|
||||||
|
VPRINT("profile %d include fixed hostlist%s\n",dpl->dp.n, hl_item->hfile->hostlist ? "" : " (empty)");
|
||||||
|
}
|
||||||
LIST_FOREACH(hl_item, &dpl->dp.hl_collection_exclude, next)
|
LIST_FOREACH(hl_item, &dpl->dp.hl_collection_exclude, next)
|
||||||
VPRINT("profile %d exclude hostlist %s%s\n",dpl->dp.n,hl_item->hfile->filename,hl_item->hfile->hostlist ? "" : " (empty)");
|
{
|
||||||
|
if (hl_item->hfile->filename)
|
||||||
|
VPRINT("profile %d exclude hostlist %s%s\n",dpl->dp.n,hl_item->hfile->filename,hl_item->hfile->hostlist ? "" : " (empty)");
|
||||||
|
else
|
||||||
|
VPRINT("profile %d exclude fixed hostlist%s\n",dpl->dp.n,hl_item->hfile->hostlist ? "" : " (empty)");
|
||||||
|
}
|
||||||
if (dpl->dp.hostlist_auto)
|
if (dpl->dp.hostlist_auto)
|
||||||
VPRINT("profile %d auto hostlist %s%s\n",dpl->dp.n,dpl->dp.hostlist_auto->filename,dpl->dp.hostlist_auto->hostlist ? "" : " (empty)");
|
VPRINT("profile %d auto hostlist %s%s\n",dpl->dp.n,dpl->dp.hostlist_auto->filename,dpl->dp.hostlist_auto->hostlist ? "" : " (empty)");
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,14 @@
|
|||||||
#include "pools.h"
|
#include "pools.h"
|
||||||
#include "params.h"
|
#include "params.h"
|
||||||
|
|
||||||
bool AppendHostList(strpool **hostlist, const char *filename);
|
bool AppendHostlistItem(hostlist_pool **hostlist, char *s);
|
||||||
|
bool AppendHostList(hostlist_pool **hostlist, const char *filename);
|
||||||
bool LoadAllHostLists();
|
bool LoadAllHostLists();
|
||||||
bool NonEmptyHostlist(strpool **hostlist);
|
bool NonEmptyHostlist(hostlist_pool **hostlist);
|
||||||
// return : true = apply fooling, false = do not apply
|
// return : true = apply fooling, false = do not apply
|
||||||
bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *excluded, bool bSkipReloadCheck);
|
bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *excluded, bool bSkipReloadCheck);
|
||||||
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename);
|
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename);
|
||||||
bool HostlistsReloadCheckForProfile(const struct desync_profile *dp);
|
bool HostlistsReloadCheckForProfile(const struct desync_profile *dp);
|
||||||
void HostlistsDebug();
|
void HostlistsDebug();
|
||||||
|
|
||||||
|
#define ResetAllHostlistsModTime() hostlist_files_reset_modtime(¶ms.hostlists)
|
||||||
|
76
tpws/ipset.c
76
tpws/ipset.c
@ -31,7 +31,7 @@ static bool addpool(ipset *ips, char **s, const char *end, int *ct)
|
|||||||
ipsetDestroy(ips);
|
ipsetDestroy(ips);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
(*ct)++;
|
if (ct) (*ct)++;
|
||||||
}
|
}
|
||||||
else if (parse_cidr6(cidr,&c6))
|
else if (parse_cidr6(cidr,&c6))
|
||||||
{
|
{
|
||||||
@ -40,7 +40,7 @@ static bool addpool(ipset *ips, char **s, const char *end, int *ct)
|
|||||||
ipsetDestroy(ips);
|
ipsetDestroy(ips);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
(*ct)++;
|
if (ct) (*ct)++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
DLOG_ERR("bad ip or subnet : %s\n",cidr);
|
DLOG_ERR("bad ip or subnet : %s\n",cidr);
|
||||||
@ -53,6 +53,11 @@ static bool addpool(ipset *ips, char **s, const char *end, int *ct)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AppendIpsetItem(ipset *ips, char *ip)
|
||||||
|
{
|
||||||
|
return addpool(ips,&ip,ip+strlen(ip),NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static bool AppendIpset(ipset *ips, const char *filename)
|
static bool AppendIpset(ipset *ips, const char *filename)
|
||||||
{
|
{
|
||||||
char *p, *e, s[256], *zbuf;
|
char *p, *e, s[256], *zbuf;
|
||||||
@ -119,21 +124,25 @@ static bool AppendIpset(ipset *ips, const char *filename)
|
|||||||
|
|
||||||
static bool LoadIpset(struct ipset_file *hfile)
|
static bool LoadIpset(struct ipset_file *hfile)
|
||||||
{
|
{
|
||||||
time_t t = file_mod_time(hfile->filename);
|
if (hfile->filename)
|
||||||
if (!t)
|
|
||||||
{
|
|
||||||
// stat() error
|
|
||||||
DLOG_ERR("cannot access ipset file '%s'. in-memory content remains unchanged.\n",hfile->filename);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (t==hfile->mod_time) return true; // up to date
|
|
||||||
ipsetDestroy(&hfile->ipset);
|
|
||||||
if (!AppendIpset(&hfile->ipset, hfile->filename))
|
|
||||||
{
|
{
|
||||||
|
file_mod_sig fsig;
|
||||||
|
if (!file_mod_signature(hfile->filename, &fsig))
|
||||||
|
{
|
||||||
|
// stat() error
|
||||||
|
DLOG_PERROR("file_mod_signature");
|
||||||
|
DLOG_ERR("cannot access ipset file '%s'. in-memory content remains unchanged.\n",hfile->filename);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (FILE_MOD_COMPARE(&hfile->mod_sig,&fsig)) return true; // up to date
|
||||||
ipsetDestroy(&hfile->ipset);
|
ipsetDestroy(&hfile->ipset);
|
||||||
return false;
|
if (!AppendIpset(&hfile->ipset, hfile->filename))
|
||||||
|
{
|
||||||
|
ipsetDestroy(&hfile->ipset);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
hfile->mod_sig=fsig;
|
||||||
}
|
}
|
||||||
hfile->mod_time=t;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
static bool LoadIpsets(struct ipset_files_head *list)
|
static bool LoadIpsets(struct ipset_files_head *list)
|
||||||
@ -205,7 +214,7 @@ static bool IpsetCheck_(const struct ipset_collection_head *ips, const struct ip
|
|||||||
|
|
||||||
LIST_FOREACH(item, ips_exclude, next)
|
LIST_FOREACH(item, ips_exclude, next)
|
||||||
{
|
{
|
||||||
VPRINT("[%s] exclude ",item->hfile->filename);
|
VPRINT("[%s] exclude ",item->hfile->filename ? item->hfile->filename : "fixed");
|
||||||
if (SearchIpset(&item->hfile->ipset, ipv4, ipv6))
|
if (SearchIpset(&item->hfile->ipset, ipv4, ipv6))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -214,7 +223,7 @@ static bool IpsetCheck_(const struct ipset_collection_head *ips, const struct ip
|
|||||||
{
|
{
|
||||||
LIST_FOREACH(item, ips, next)
|
LIST_FOREACH(item, ips, next)
|
||||||
{
|
{
|
||||||
VPRINT("[%s] include ",item->hfile->filename);
|
VPRINT("[%s] include ",item->hfile->filename ? item->hfile->filename : "fixed");
|
||||||
if (SearchIpset(&item->hfile->ipset, ipv4, ipv6))
|
if (SearchIpset(&item->hfile->ipset, ipv4, ipv6))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -234,17 +243,27 @@ bool IpsetCheck(const struct desync_profile *dp, const struct in_addr *ipv4, con
|
|||||||
static struct ipset_file *RegisterIpset_(struct ipset_files_head *ipsets, struct ipset_collection_head *ips_collection, const char *filename)
|
static struct ipset_file *RegisterIpset_(struct ipset_files_head *ipsets, struct ipset_collection_head *ips_collection, const char *filename)
|
||||||
{
|
{
|
||||||
struct ipset_file *hfile;
|
struct ipset_file *hfile;
|
||||||
if (!(hfile=ipset_files_search(ipsets, filename)))
|
if (filename)
|
||||||
if (!(hfile=ipset_files_add(ipsets, filename)))
|
{
|
||||||
|
if (!(hfile=ipset_files_search(ipsets, filename)))
|
||||||
|
if (!(hfile=ipset_files_add(ipsets, filename)))
|
||||||
|
return NULL;
|
||||||
|
if (!ipset_collection_search(ips_collection, filename))
|
||||||
|
if (!ipset_collection_add(ips_collection, hfile))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(hfile=ipset_files_add(ipsets, NULL)))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!ipset_collection_search(ips_collection, filename))
|
|
||||||
if (!ipset_collection_add(ips_collection, hfile))
|
if (!ipset_collection_add(ips_collection, hfile))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
return hfile;
|
return hfile;
|
||||||
}
|
}
|
||||||
struct ipset_file *RegisterIpset(struct desync_profile *dp, bool bExclude, const char *filename)
|
struct ipset_file *RegisterIpset(struct desync_profile *dp, bool bExclude, const char *filename)
|
||||||
{
|
{
|
||||||
if (!file_mod_time(filename))
|
if (filename && !file_mod_time(filename))
|
||||||
{
|
{
|
||||||
DLOG_ERR("cannot access ipset file '%s'\n",filename);
|
DLOG_ERR("cannot access ipset file '%s'\n",filename);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -277,13 +296,24 @@ void IpsetsDebug()
|
|||||||
struct ipset_item *ips_item;
|
struct ipset_item *ips_item;
|
||||||
|
|
||||||
LIST_FOREACH(hfile, ¶ms.ipsets, next)
|
LIST_FOREACH(hfile, ¶ms.ipsets, next)
|
||||||
VPRINT("ipset file %s (%s)\n",hfile->filename,dbg_ipset_fill(&hfile->ipset));
|
{
|
||||||
|
if (hfile->filename)
|
||||||
|
VPRINT("ipset file %s (%s)\n",hfile->filename,dbg_ipset_fill(&hfile->ipset));
|
||||||
|
else
|
||||||
|
VPRINT("ipset fixed (%s)\n",dbg_ipset_fill(&hfile->ipset));
|
||||||
|
}
|
||||||
|
|
||||||
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
||||||
{
|
{
|
||||||
LIST_FOREACH(ips_item, &dpl->dp.ips_collection, next)
|
LIST_FOREACH(ips_item, &dpl->dp.ips_collection, next)
|
||||||
VPRINT("profile %d include ipset %s (%s)\n",dpl->dp.n,ips_item->hfile->filename,dbg_ipset_fill(&ips_item->hfile->ipset));
|
if (ips_item->hfile->filename)
|
||||||
|
VPRINT("profile %d include ipset %s (%s)\n",dpl->dp.n,ips_item->hfile->filename,dbg_ipset_fill(&ips_item->hfile->ipset));
|
||||||
|
else
|
||||||
|
VPRINT("profile %d include fixed ipset (%s)\n",dpl->dp.n,dbg_ipset_fill(&ips_item->hfile->ipset));
|
||||||
LIST_FOREACH(ips_item, &dpl->dp.ips_collection_exclude, next)
|
LIST_FOREACH(ips_item, &dpl->dp.ips_collection_exclude, next)
|
||||||
VPRINT("profile %d exclude ipset %s (%s)\n",dpl->dp.n,ips_item->hfile->filename,dbg_ipset_fill(&ips_item->hfile->ipset));
|
if (ips_item->hfile->filename)
|
||||||
|
VPRINT("profile %d exclude ipset %s (%s)\n",dpl->dp.n,ips_item->hfile->filename,dbg_ipset_fill(&ips_item->hfile->ipset));
|
||||||
|
else
|
||||||
|
VPRINT("profile %d exclude fixed ipset (%s)\n",dpl->dp.n,dbg_ipset_fill(&ips_item->hfile->ipset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,3 +9,6 @@ bool LoadAllIpsets();
|
|||||||
bool IpsetCheck(const struct desync_profile *dp, const struct in_addr *ipv4, const struct in6_addr *ipv6);
|
bool IpsetCheck(const struct desync_profile *dp, const struct in_addr *ipv4, const struct in6_addr *ipv6);
|
||||||
struct ipset_file *RegisterIpset(struct desync_profile *dp, bool bExclude, const char *filename);
|
struct ipset_file *RegisterIpset(struct desync_profile *dp, bool bExclude, const char *filename);
|
||||||
void IpsetsDebug();
|
void IpsetsDebug();
|
||||||
|
bool AppendIpsetItem(ipset *ips, char *ip);
|
||||||
|
|
||||||
|
#define ResetAllIpsetModTime() ipset_files_reset_modtime(¶ms.ipsets)
|
||||||
|
111
tpws/linux_compat.h
Normal file
111
tpws/linux_compat.h
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#ifdef __linux__
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#ifndef TCP_USER_TIMEOUT
|
||||||
|
#define TCP_USER_TIMEOUT 18
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef IP6T_SO_ORIGINAL_DST
|
||||||
|
#define IP6T_SO_ORIGINAL_DST 80
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PR_SET_NO_NEW_PRIVS
|
||||||
|
#define PR_SET_NO_NEW_PRIVS 38
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// workaround for old headers
|
||||||
|
|
||||||
|
struct tcp_info_new {
|
||||||
|
__u8 tcpi_state;
|
||||||
|
__u8 tcpi_ca_state;
|
||||||
|
__u8 tcpi_retransmits;
|
||||||
|
__u8 tcpi_probes;
|
||||||
|
__u8 tcpi_backoff;
|
||||||
|
__u8 tcpi_options;
|
||||||
|
__u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
|
||||||
|
__u8 tcpi_delivery_rate_app_limited : 1, tcpi_fastopen_client_fail : 2;
|
||||||
|
|
||||||
|
__u32 tcpi_rto;
|
||||||
|
__u32 tcpi_ato;
|
||||||
|
__u32 tcpi_snd_mss;
|
||||||
|
__u32 tcpi_rcv_mss;
|
||||||
|
|
||||||
|
__u32 tcpi_unacked;
|
||||||
|
__u32 tcpi_sacked;
|
||||||
|
__u32 tcpi_lost;
|
||||||
|
__u32 tcpi_retrans;
|
||||||
|
__u32 tcpi_fackets;
|
||||||
|
|
||||||
|
/* Times. */
|
||||||
|
__u32 tcpi_last_data_sent;
|
||||||
|
__u32 tcpi_last_ack_sent; /* Not remembered, sorry. */
|
||||||
|
__u32 tcpi_last_data_recv;
|
||||||
|
__u32 tcpi_last_ack_recv;
|
||||||
|
|
||||||
|
/* Metrics. */
|
||||||
|
__u32 tcpi_pmtu;
|
||||||
|
__u32 tcpi_rcv_ssthresh;
|
||||||
|
__u32 tcpi_rtt;
|
||||||
|
__u32 tcpi_rttvar;
|
||||||
|
__u32 tcpi_snd_ssthresh;
|
||||||
|
__u32 tcpi_snd_cwnd;
|
||||||
|
__u32 tcpi_advmss;
|
||||||
|
__u32 tcpi_reordering;
|
||||||
|
|
||||||
|
__u32 tcpi_rcv_rtt;
|
||||||
|
__u32 tcpi_rcv_space;
|
||||||
|
|
||||||
|
__u32 tcpi_total_retrans;
|
||||||
|
|
||||||
|
__u64 tcpi_pacing_rate;
|
||||||
|
__u64 tcpi_max_pacing_rate;
|
||||||
|
__u64 tcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */
|
||||||
|
__u64 tcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */
|
||||||
|
__u32 tcpi_segs_out; /* RFC4898 tcpEStatsPerfSegsOut */
|
||||||
|
__u32 tcpi_segs_in; /* RFC4898 tcpEStatsPerfSegsIn */
|
||||||
|
|
||||||
|
__u32 tcpi_notsent_bytes;
|
||||||
|
__u32 tcpi_min_rtt;
|
||||||
|
__u32 tcpi_data_segs_in; /* RFC4898 tcpEStatsDataSegsIn */
|
||||||
|
__u32 tcpi_data_segs_out; /* RFC4898 tcpEStatsDataSegsOut */
|
||||||
|
|
||||||
|
__u64 tcpi_delivery_rate;
|
||||||
|
|
||||||
|
__u64 tcpi_busy_time; /* Time (usec) busy sending data */
|
||||||
|
__u64 tcpi_rwnd_limited; /* Time (usec) limited by receive window */
|
||||||
|
__u64 tcpi_sndbuf_limited; /* Time (usec) limited by send buffer */
|
||||||
|
|
||||||
|
__u32 tcpi_delivered;
|
||||||
|
__u32 tcpi_delivered_ce;
|
||||||
|
|
||||||
|
__u64 tcpi_bytes_sent; /* RFC4898 tcpEStatsPerfHCDataOctetsOut */
|
||||||
|
__u64 tcpi_bytes_retrans; /* RFC4898 tcpEStatsPerfOctetsRetrans */
|
||||||
|
__u32 tcpi_dsack_dups; /* RFC4898 tcpEStatsStackDSACKDups */
|
||||||
|
__u32 tcpi_reord_seen; /* reordering events seen */
|
||||||
|
|
||||||
|
__u32 tcpi_rcv_ooopack; /* Out-of-order packets received */
|
||||||
|
|
||||||
|
__u32 tcpi_snd_wnd; /* peer's advertised receive window after
|
||||||
|
* scaling (bytes)
|
||||||
|
*/
|
||||||
|
__u32 tcpi_rcv_wnd; /* local advertised receive window after
|
||||||
|
* scaling (bytes)
|
||||||
|
*/
|
||||||
|
|
||||||
|
__u32 tcpi_rehash; /* PLB or timeout triggered rehash attempts */
|
||||||
|
|
||||||
|
__u16 tcpi_total_rto; /* Total number of RTO timeouts, including
|
||||||
|
* SYN/SYN-ACK and recurring timeouts.
|
||||||
|
*/
|
||||||
|
__u16 tcpi_total_rto_recoveries; /* Total number of RTO
|
||||||
|
* recoveries, including any
|
||||||
|
* unfinished recovery.
|
||||||
|
*/
|
||||||
|
__u32 tcpi_total_rto_time; /* Total time spent in RTO recoveries
|
||||||
|
* in milliseconds, including any
|
||||||
|
* unfinished recovery.
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -50,6 +50,7 @@ static int DLOG_VA(const char *format, int syslog_priority, bool condup, int lev
|
|||||||
{
|
{
|
||||||
va_copy(args2,args);
|
va_copy(args2,args);
|
||||||
DLOG_CON(format,syslog_priority,args2);
|
DLOG_CON(format,syslog_priority,args2);
|
||||||
|
va_end(args2);
|
||||||
}
|
}
|
||||||
if (params.debug>=level)
|
if (params.debug>=level)
|
||||||
{
|
{
|
||||||
@ -155,22 +156,26 @@ void hexdump_limited_dlog(const uint8_t *data, size_t size, size_t limit)
|
|||||||
if (bcut) VPRINT(" ...");
|
if (bcut) VPRINT(" ...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dp_init(struct desync_profile *dp)
|
||||||
|
{
|
||||||
|
LIST_INIT(&dp->hl_collection);
|
||||||
|
LIST_INIT(&dp->hl_collection_exclude);
|
||||||
|
LIST_INIT(&dp->ips_collection);
|
||||||
|
LIST_INIT(&dp->ips_collection_exclude);
|
||||||
|
LIST_INIT(&dp->pf_tcp);
|
||||||
|
|
||||||
|
dp->filter_ipv4 = dp->filter_ipv6 = true;
|
||||||
|
memcpy(dp->hostspell, "host", 4); // default hostspell
|
||||||
|
dp->hostlist_auto_fail_threshold = HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT;
|
||||||
|
dp->hostlist_auto_fail_time = HOSTLIST_AUTO_FAIL_TIME_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
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 = calloc(1,sizeof(struct desync_profile_list));
|
struct desync_profile_list *entry = calloc(1,sizeof(struct desync_profile_list));
|
||||||
if (!entry) return NULL;
|
if (!entry) return NULL;
|
||||||
|
|
||||||
LIST_INIT(&entry->dp.hl_collection);
|
dp_init(&entry->dp);
|
||||||
LIST_INIT(&entry->dp.hl_collection_exclude);
|
|
||||||
LIST_INIT(&entry->dp.ips_collection);
|
|
||||||
LIST_INIT(&entry->dp.ips_collection_exclude);
|
|
||||||
LIST_INIT(&entry->dp.pf_tcp);
|
|
||||||
|
|
||||||
entry->dp.filter_ipv4 = entry->dp.filter_ipv6 = true;
|
|
||||||
memcpy(entry->dp.hostspell, "host", 4); // default hostspell
|
|
||||||
entry->dp.hostlist_auto_fail_threshold = HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT;
|
|
||||||
entry->dp.hostlist_auto_fail_time = HOSTLIST_AUTO_FAIL_TIME_DEFAULT;
|
|
||||||
|
|
||||||
// add to the tail
|
// add to the tail
|
||||||
struct desync_profile_list *dpn,*dpl=LIST_FIRST(¶ms.desync_profiles);
|
struct desync_profile_list *dpn,*dpl=LIST_FIRST(¶ms.desync_profiles);
|
||||||
@ -184,14 +189,23 @@ struct desync_profile_list *dp_list_add(struct desync_profile_list_head *head)
|
|||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
static void dp_entry_destroy(struct desync_profile_list *entry)
|
static void dp_clear_dynamic(struct desync_profile *dp)
|
||||||
{
|
{
|
||||||
hostlist_collection_destroy(&entry->dp.hl_collection);
|
hostlist_collection_destroy(&dp->hl_collection);
|
||||||
hostlist_collection_destroy(&entry->dp.hl_collection_exclude);
|
hostlist_collection_destroy(&dp->hl_collection_exclude);
|
||||||
ipset_collection_destroy(&entry->dp.ips_collection);
|
ipset_collection_destroy(&dp->ips_collection);
|
||||||
ipset_collection_destroy(&entry->dp.ips_collection_exclude);
|
ipset_collection_destroy(&dp->ips_collection_exclude);
|
||||||
port_filters_destroy(&entry->dp.pf_tcp);
|
port_filters_destroy(&dp->pf_tcp);
|
||||||
HostFailPoolDestroy(&entry->dp.hostlist_auto_fail_counters);
|
HostFailPoolDestroy(&dp->hostlist_auto_fail_counters);
|
||||||
|
}
|
||||||
|
void dp_clear(struct desync_profile *dp)
|
||||||
|
{
|
||||||
|
dp_clear_dynamic(dp);
|
||||||
|
memset(dp,0,sizeof(*dp));
|
||||||
|
}
|
||||||
|
void dp_entry_destroy(struct desync_profile_list *entry)
|
||||||
|
{
|
||||||
|
dp_clear_dynamic(&entry->dp);
|
||||||
free(entry);
|
free(entry);
|
||||||
}
|
}
|
||||||
void dp_list_destroy(struct desync_profile_list_head *head)
|
void dp_list_destroy(struct desync_profile_list_head *head)
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#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
|
||||||
|
|
||||||
#define FIX_SEG_DEFAULT_MAX_WAIT 30
|
#define FIX_SEG_DEFAULT_MAX_WAIT 50
|
||||||
|
|
||||||
enum bindll { unwanted=0, no, prefer, force };
|
enum bindll { unwanted=0, no, prefer, force };
|
||||||
|
|
||||||
@ -83,7 +83,10 @@ struct desync_profile_list {
|
|||||||
};
|
};
|
||||||
LIST_HEAD(desync_profile_list_head, desync_profile_list);
|
LIST_HEAD(desync_profile_list_head, desync_profile_list);
|
||||||
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);
|
||||||
|
void dp_entry_destroy(struct desync_profile_list *entry);
|
||||||
void dp_list_destroy(struct desync_profile_list_head *head);
|
void dp_list_destroy(struct desync_profile_list_head *head);
|
||||||
|
void dp_init(struct desync_profile *dp);
|
||||||
|
void dp_clear(struct desync_profile *dp);
|
||||||
|
|
||||||
struct params_s
|
struct params_s
|
||||||
{
|
{
|
||||||
|
82
tpws/pools.c
82
tpws/pools.c
@ -31,6 +31,9 @@
|
|||||||
free(elem); \
|
free(elem); \
|
||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
|
#define ADD_HOSTLIST_POOL(etype, ppool, keystr, keystr_len, flg) \
|
||||||
|
ADD_STR_POOL(etype,ppool,keystr,keystr_len); \
|
||||||
|
elem->flags = flg;
|
||||||
|
|
||||||
|
|
||||||
#undef uthash_nonfatal_oom
|
#undef uthash_nonfatal_oom
|
||||||
@ -42,27 +45,31 @@ static void ut_oom_recover(void *elem)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for not zero terminated strings
|
// for not zero terminated strings
|
||||||
bool StrPoolAddStrLen(strpool **pp, const char *s, size_t slen)
|
bool HostlistPoolAddStrLen(hostlist_pool **pp, const char *s, size_t slen, uint32_t flags)
|
||||||
{
|
{
|
||||||
ADD_STR_POOL(strpool, pp, s, slen)
|
ADD_HOSTLIST_POOL(hostlist_pool, pp, s, slen, flags)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// for zero terminated strings
|
// for zero terminated strings
|
||||||
bool StrPoolAddStr(strpool **pp, const char *s)
|
bool HostlistPoolAddStr(hostlist_pool **pp, const char *s, uint32_t flags)
|
||||||
{
|
{
|
||||||
return StrPoolAddStrLen(pp, s, strlen(s));
|
return HostlistPoolAddStrLen(pp, s, strlen(s), flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StrPoolCheckStr(strpool *p, const char *s)
|
hostlist_pool *HostlistPoolGetStr(hostlist_pool *p, const char *s)
|
||||||
{
|
{
|
||||||
strpool *elem;
|
hostlist_pool *elem;
|
||||||
HASH_FIND_STR(p, s, elem);
|
HASH_FIND_STR(p, s, elem);
|
||||||
return elem != NULL;
|
return elem;
|
||||||
|
}
|
||||||
|
bool HostlistPoolCheckStr(hostlist_pool *p, const char *s)
|
||||||
|
{
|
||||||
|
return !!HostlistPoolGetStr(p,s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StrPoolDestroy(strpool **pp)
|
void HostlistPoolDestroy(hostlist_pool **pp)
|
||||||
{
|
{
|
||||||
DESTROY_STR_POOL(strpool, pp)
|
DESTROY_STR_POOL(hostlist_pool, pp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -139,7 +146,7 @@ bool strlist_add(struct str_list_head *head, const char *filename)
|
|||||||
}
|
}
|
||||||
static void strlist_entry_destroy(struct str_list *entry)
|
static void strlist_entry_destroy(struct str_list *entry)
|
||||||
{
|
{
|
||||||
if (entry->str) free(entry->str);
|
free(entry->str);
|
||||||
free(entry);
|
free(entry);
|
||||||
}
|
}
|
||||||
void strlist_destroy(struct str_list_head *head)
|
void strlist_destroy(struct str_list_head *head)
|
||||||
@ -154,18 +161,22 @@ void strlist_destroy(struct str_list_head *head)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const char *filename)
|
struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const char *filename)
|
||||||
{
|
{
|
||||||
struct hostlist_file *entry = malloc(sizeof(struct hostlist_file));
|
struct hostlist_file *entry = malloc(sizeof(struct hostlist_file));
|
||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
if (!(entry->filename = strdup(filename)))
|
if (filename)
|
||||||
{
|
{
|
||||||
free(entry);
|
if (!(entry->filename = strdup(filename)))
|
||||||
return false;
|
{
|
||||||
|
free(entry);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
entry->mod_time=0;
|
else
|
||||||
|
entry->filename = NULL;
|
||||||
|
FILE_MOD_RESET(&entry->mod_sig);
|
||||||
entry->hostlist = NULL;
|
entry->hostlist = NULL;
|
||||||
LIST_INSERT_HEAD(head, entry, next);
|
LIST_INSERT_HEAD(head, entry, next);
|
||||||
}
|
}
|
||||||
@ -173,8 +184,8 @@ struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const
|
|||||||
}
|
}
|
||||||
static void hostlist_files_entry_destroy(struct hostlist_file *entry)
|
static void hostlist_files_entry_destroy(struct hostlist_file *entry)
|
||||||
{
|
{
|
||||||
if (entry->filename) free(entry->filename);
|
free(entry->filename);
|
||||||
StrPoolDestroy(&entry->hostlist);
|
HostlistPoolDestroy(&entry->hostlist);
|
||||||
free(entry);
|
free(entry);
|
||||||
}
|
}
|
||||||
void hostlist_files_destroy(struct hostlist_files_head *head)
|
void hostlist_files_destroy(struct hostlist_files_head *head)
|
||||||
@ -192,11 +203,18 @@ struct hostlist_file *hostlist_files_search(struct hostlist_files_head *head, co
|
|||||||
|
|
||||||
LIST_FOREACH(hfile, head, next)
|
LIST_FOREACH(hfile, head, next)
|
||||||
{
|
{
|
||||||
if (!strcmp(hfile->filename,filename))
|
if (hfile->filename && !strcmp(hfile->filename,filename))
|
||||||
return hfile;
|
return hfile;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
void hostlist_files_reset_modtime(struct hostlist_files_head *list)
|
||||||
|
{
|
||||||
|
struct hostlist_file *hfile;
|
||||||
|
|
||||||
|
LIST_FOREACH(hfile, list, next)
|
||||||
|
FILE_MOD_RESET(&hfile->mod_sig);
|
||||||
|
}
|
||||||
|
|
||||||
struct hostlist_item *hostlist_collection_add(struct hostlist_collection_head *head, struct hostlist_file *hfile)
|
struct hostlist_item *hostlist_collection_add(struct hostlist_collection_head *head, struct hostlist_file *hfile)
|
||||||
{
|
{
|
||||||
@ -223,7 +241,7 @@ struct hostlist_item *hostlist_collection_search(struct hostlist_collection_head
|
|||||||
|
|
||||||
LIST_FOREACH(item, head, next)
|
LIST_FOREACH(item, head, next)
|
||||||
{
|
{
|
||||||
if (!strcmp(item->hfile->filename,filename))
|
if (item->hfile->filename && !strcmp(item->hfile->filename,filename))
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -369,12 +387,17 @@ struct ipset_file *ipset_files_add(struct ipset_files_head *head, const char *fi
|
|||||||
struct ipset_file *entry = malloc(sizeof(struct ipset_file));
|
struct ipset_file *entry = malloc(sizeof(struct ipset_file));
|
||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
if (!(entry->filename = strdup(filename)))
|
if (filename)
|
||||||
{
|
{
|
||||||
free(entry);
|
if (!(entry->filename = strdup(filename)))
|
||||||
return false;
|
{
|
||||||
|
free(entry);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
entry->mod_time=0;
|
else
|
||||||
|
entry->filename = NULL;
|
||||||
|
FILE_MOD_RESET(&entry->mod_sig);
|
||||||
memset(&entry->ipset,0,sizeof(entry->ipset));
|
memset(&entry->ipset,0,sizeof(entry->ipset));
|
||||||
LIST_INSERT_HEAD(head, entry, next);
|
LIST_INSERT_HEAD(head, entry, next);
|
||||||
}
|
}
|
||||||
@ -382,7 +405,7 @@ struct ipset_file *ipset_files_add(struct ipset_files_head *head, const char *fi
|
|||||||
}
|
}
|
||||||
static void ipset_files_entry_destroy(struct ipset_file *entry)
|
static void ipset_files_entry_destroy(struct ipset_file *entry)
|
||||||
{
|
{
|
||||||
if (entry->filename) free(entry->filename);
|
free(entry->filename);
|
||||||
ipsetDestroy(&entry->ipset);
|
ipsetDestroy(&entry->ipset);
|
||||||
free(entry);
|
free(entry);
|
||||||
}
|
}
|
||||||
@ -401,11 +424,18 @@ struct ipset_file *ipset_files_search(struct ipset_files_head *head, const char
|
|||||||
|
|
||||||
LIST_FOREACH(hfile, head, next)
|
LIST_FOREACH(hfile, head, next)
|
||||||
{
|
{
|
||||||
if (!strcmp(hfile->filename,filename))
|
if (hfile->filename && !strcmp(hfile->filename,filename))
|
||||||
return hfile;
|
return hfile;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
void ipset_files_reset_modtime(struct ipset_files_head *list)
|
||||||
|
{
|
||||||
|
struct ipset_file *hfile;
|
||||||
|
|
||||||
|
LIST_FOREACH(hfile, list, next)
|
||||||
|
FILE_MOD_RESET(&hfile->mod_sig);
|
||||||
|
}
|
||||||
|
|
||||||
struct ipset_item *ipset_collection_add(struct ipset_collection_head *head, struct ipset_file *hfile)
|
struct ipset_item *ipset_collection_add(struct ipset_collection_head *head, struct ipset_file *hfile)
|
||||||
{
|
{
|
||||||
@ -432,7 +462,7 @@ struct ipset_item *ipset_collection_search(struct ipset_collection_head *head, c
|
|||||||
|
|
||||||
LIST_FOREACH(item, head, next)
|
LIST_FOREACH(item, head, next)
|
||||||
{
|
{
|
||||||
if (!strcmp(item->hfile->filename,filename))
|
if (item->hfile->filename && !strcmp(item->hfile->filename,filename))
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user