31 Commits

Author SHA1 Message Date
Vadim Vetrov
f5a6c5718f Do not duplicate default CFLAGS 2024-12-01 18:24:30 +03:00
Vadim Vetrov
aefabe7e0a Fix SIGSEGV/stacksmash in UDP logger.
The bug was reported in #197. Caused by insufficient size of logging
buffer.
2024-12-01 18:19:09 +03:00
Vadim Vetrov
fd1ae1e574 Move entware builders from entware branch to openwrt 2024-11-30 14:15:14 +03:00
Vadim Vetrov
7303abdaf2 Merge pull request #174 from Waujito/daemonize
Daemonize youtubeUnblock with flags, without any overhead
2024-11-29 23:24:50 +03:00
Vadim Vetrov
cb138b902a Improve UDP payload logging 2024-11-29 21:43:27 +03:00
Vadim Vetrov
3a5dbff8ac Update kmod logging 2024-11-29 21:42:57 +03:00
Vadim Vetrov
62551a9f82 Replace incrementing defines with one enum 2024-11-29 11:22:55 +03:00
Vadim Vetrov
ef120ca100 Update logging
Add syslog for daemonize. This allows to log not only to the standard
output but also in system log
2024-11-29 11:22:55 +03:00
Vadim Vetrov
a4975dcdcd Daemonize youtubeUnblock with flags, without any overhead 2024-11-29 11:22:54 +03:00
Vadim Vetrov
7ec29bd47b Merge pull request #193 from Waujito/workflow_update
Move workflow binaries builds to docker instead of cache
2024-11-29 11:07:55 +03:00
Vadim Vetrov
20ce07821b Move test builders from cache to docker 2024-11-29 10:56:01 +03:00
Vadim Vetrov
eb544c11ce Entware binaries on docker instead of cache 2024-11-29 09:54:09 +03:00
Vadim Vetrov
3376860c0f Kyber on firefox 2024-11-26 18:47:29 +03:00
Vadim Vetrov
438a3c17d8 Update workflows
musl-cross and openwrt sdk docker image implemented breaking updates.
2024-11-26 18:08:47 +03:00
Vadim Vetrov
046ecc4c97 Merge pull request #191 from MayanKoyote/main-dev
README.md & args.c: minor correction of typos
2024-11-25 23:56:34 +03:00
MayanKoyote
bb8992578f args.c: minor correction of typos 2024-11-26 00:25:35 +05:00
MayanKoyote
cb46c89423 README.md & args.c: minor correction of typos 2024-11-26 00:15:10 +05:00
Vadim Vetrov
d87d3c9efb Old openwrt (#168) 2024-11-02 10:56:44 +03:00
Vadim Vetrov
562f17e932 Merge branch 'dev' 2024-10-29 12:04:51 +03:00
Vadim Vetrov
56b6126f52 Mention --queue-balance in multithreading flag
Raw threading lead to confusion like in #177
2024-10-29 11:59:46 +03:00
Vadim Vetrov
235bf823db Add issue templates 2024-10-29 11:11:29 +03:00
Vadim Vetrov
c9537bae95 Add versioning 2024-10-29 01:55:37 +03:00
Vadim Vetrov
0ee6d667e4 Fix starting logs 2024-10-29 00:12:27 +03:00
Vadim Vetrov
aa96769559 Fix youtubeUnblock freeze when more than queue_size packets being sent
as fake_sni_seq_len

The problem affects both the userspace version and kernel space one. The
problem was reported in #166 and hopefully #167 also relates to it. The
problem occures because each packet sent by rawsocket is being enqueued
in the nf_queue, but each rawsocket waits for the packet to be
processed by linux kernel network stack. This leads to the infinitily
waiting rawsocket when the queue fullfills.
2024-10-27 02:42:06 +03:00
Vadim Vetrov
ae9592c71f Userspace: handle --no-ipv6 for PF_INET6 UNBIND/BIND_PF 2024-10-27 00:09:45 +03:00
Vadim Vetrov
93972f8404 Update Padavan manual (#163) 2024-10-26 18:04:24 +03:00
Vadim Vetrov
7070ddfc74 Userspace: better support for ALLOC_MALLOC
An alternative memory allocation strategy for userspace
2024-10-26 14:50:21 +03:00
Vadim Vetrov
0e9b3ff018 Add notice about kmods in readme 2024-10-25 22:28:39 +03:00
Vadim Vetrov
f344e525d2 Add armv7sf 2024-10-25 22:11:21 +03:00
Vadim Vetrov
f1ab2ac1a9 Userspace youtubeUnblock: support kernel versions less than 3.8
The behaviour of nfnetlink_queue is changed since then but old kernels
require BIND/UNBIND_PF commands.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0360ae412d09bc6f4864c801effcb20bfd84520e

Co-Authored-by: renr4 <renr4@users.noreply.github.com>
2024-10-22 17:51:41 +03:00
renr
55d359d3e7 Padavan support 2024-10-19 22:46:42 +03:00
36 changed files with 672 additions and 380 deletions

42
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,42 @@
name: Bug report
description: Use this issue template when you are pretty sure here is a bug. Make sure the trouble you are experiencing haven't been already reported earlier and haven't been talked about in discussions.
body:
- type: markdown
attributes:
value: |
Use this issue template when you are pretty sure here is a bug.
Make sure the trouble you are experiencing haven't been already reported earlier and haven't been talked about in [discussions](https://github.com/Waujito/youtubeUnblock/discussions).
Note, that *bugs* are internal program errors: crashes, freezes and other types of undefined behavior. You may also report problems with routers infrastructure here, but **NOT** questions like *My router doesn't work help please*. Your questions and other stuff with custom routers setup should be discussed [here](https://github.com/Waujito/youtubeUnblock/discussions/172)
Discuss problems like *youtube doesn't unblock* [here](https://github.com/Waujito/youtubeUnblock/discussions/173)
- type: textarea
id: bug-report
attributes:
label: Bug description
validations:
required: true
- type: input
id: linux-distro
attributes:
label: Linux distribution
description: Pass here your linux distro e.g. OpenWRT, Entware, Merlin, Padavan, Ubuntu, Debian
validations:
required: false
- type: textarea
id: architecture
attributes:
label: Device architecture
description: Pass here the architecture of your device. (On openwrt do `cat /etc/openwrt_release`, on other systems `lscpu` or `cat /proc/cpuinfo`)
validations:
required: false
- type: textarea
id: configs
attributes:
label: Configuration
description: Pass here the configuration of youtubeUnblock being used. You may pass output of `cat /etc/config/youtubeUnblock` on OpenWRT or raw flags of youtubeUnblock.
validations:
required: false

View File

@@ -0,0 +1,10 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---

1
.github/builder_containers/README.md vendored Normal file
View File

@@ -0,0 +1 @@
This directory contains dockerfiles for large docker containers. This allows not to rebuild binaries every build and not to utilize cache.

View File

@@ -0,0 +1,6 @@
FROM waujito/entware_builder
RUN git clone --depth 1 https://github.com/Entware/Entware.git
WORKDIR /home/me/Entware
RUN make package/symlinks
RUN cp -v configs/aarch64-3.10.config .config
RUN make -j$(nproc) toolchain/install

View File

@@ -0,0 +1,6 @@
FROM waujito/entware_builder
RUN git clone --depth 1 https://github.com/Entware/Entware.git -b k2.6
WORKDIR /home/me/Entware
RUN make package/symlinks
RUN cp -v configs/armv7-2.6.config .config
RUN make -j$(nproc) toolchain/install

View File

@@ -0,0 +1,6 @@
FROM waujito/entware_builder
RUN git clone --depth 1 https://github.com/Entware/Entware.git
WORKDIR /home/me/Entware
RUN make package/symlinks
RUN cp -v configs/armv7-3.2.config .config
RUN make -j$(nproc) toolchain/install

View File

@@ -0,0 +1,6 @@
FROM waujito/entware_builder
RUN git clone --depth 1 https://github.com/Entware/Entware.git
WORKDIR /home/me/Entware
RUN make package/symlinks
RUN cp -v configs/mips-3.4.config .config
RUN make -j$(nproc) toolchain/install

View File

@@ -0,0 +1,6 @@
FROM waujito/entware_builder
RUN git clone --depth 1 https://github.com/Entware/Entware.git
WORKDIR /home/me/Entware
RUN make package/symlinks
RUN cp -v configs/mipsel-3.4.config .config
RUN make -j$(nproc) toolchain/install

View File

@@ -0,0 +1,6 @@
FROM waujito/entware_builder
RUN git clone --depth 1 https://github.com/Entware/Entware.git
WORKDIR /home/me/Entware
RUN make package/symlinks
RUN cp -v configs/x64-3.2.config .config
RUN make -j$(nproc) toolchain/install

View File

@@ -0,0 +1,6 @@
FROM waujito/entware_builder
RUN git clone --depth 1 https://github.com/Entware/Entware.git -b k2.6
WORKDIR /home/me/Entware
RUN make package/symlinks
RUN cp -v configs/x86-2.6.config .config
RUN make -j$(nproc) toolchain/install

View File

@@ -0,0 +1,12 @@
FROM ubuntu:14.04
RUN apt update && apt install -y build-essential flex bc bison libelf-dev elfutils libssl-dev wget
RUN wget https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.0.101.tar.xz -O kernel.tar.xz
RUN tar -xf kernel.tar.xz
RUN rm -f kernel.tar.xz
RUN /bin/bash -c "mv linux-* linux"
WORKDIR /linux
RUN make defconfig
RUN make -j$(nproc)

View File

@@ -0,0 +1,12 @@
FROM ubuntu:16.04
RUN apt update && apt install -y build-essential flex bc bison libelf-dev elfutils libssl-dev wget
RUN wget https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.10.108.tar.xz -O kernel.tar.xz
RUN tar -xf kernel.tar.xz
RUN rm -f kernel.tar.xz
RUN /bin/bash -c "mv linux-* linux"
WORKDIR /linux
RUN make defconfig
RUN make -j$(nproc)

View File

@@ -0,0 +1,12 @@
FROM ubuntu:24.04
RUN apt update && apt install -y build-essential flex bc bison libelf-dev elfutils libssl-dev wget
RUN wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.19.322.tar.xz -O kernel.tar.xz
RUN tar -xf kernel.tar.xz
RUN rm -f kernel.tar.xz
RUN /bin/bash -c "mv linux-* linux"
WORKDIR /linux
RUN make defconfig
RUN make -j$(nproc)

View File

@@ -0,0 +1,12 @@
FROM ubuntu:24.04
RUN apt update && apt install -y build-essential flex bc bison libelf-dev elfutils libssl-dev wget
RUN wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.302.tar.xz -O kernel.tar.xz
RUN tar -xf kernel.tar.xz
RUN rm -f kernel.tar.xz
RUN /bin/bash -c "mv linux-* linux"
WORKDIR /linux
RUN make defconfig
RUN make -j$(nproc)

View File

@@ -0,0 +1,12 @@
FROM ubuntu:24.04
RUN apt update && apt install -y build-essential flex bc bison libelf-dev elfutils libssl-dev wget
RUN wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.167.tar.xz -O kernel.tar.xz
RUN tar -xf kernel.tar.xz
RUN rm -f kernel.tar.xz
RUN /bin/bash -c "mv linux-* linux"
WORKDIR /linux
RUN make defconfig
RUN make -j$(nproc)

View File

@@ -0,0 +1,12 @@
FROM ubuntu:24.04
RUN apt update && apt install -y build-essential flex bc bison libelf-dev elfutils libssl-dev wget
RUN wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.4.284.tar.xz -O kernel.tar.xz
RUN tar -xf kernel.tar.xz
RUN rm -f kernel.tar.xz
RUN /bin/bash -c "mv linux-* linux"
WORKDIR /linux
RUN make defconfig
RUN make -j$(nproc)

View File

@@ -0,0 +1,12 @@
FROM ubuntu:24.04
RUN apt update && apt install -y build-essential flex bc bison libelf-dev elfutils libssl-dev wget
RUN wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.52.tar.xz -O kernel.tar.xz
RUN tar -xf kernel.tar.xz
RUN rm -f kernel.tar.xz
RUN /bin/bash -c "mv linux-* linux"
WORKDIR /linux
RUN make defconfig
RUN make -j$(nproc)

View File

@@ -10,18 +10,18 @@ on:
- 'LICENSE' - 'LICENSE'
- 'README.md' - 'README.md'
workflow_dispatch: workflow_dispatch:
pull_request:
jobs: jobs:
prepare: prepare:
runs-on: ubuntu-latest runs-on: ubuntu-latest
outputs: outputs:
version: ${{ steps.gh.outputs.version }} version: ${{ steps.gh.outputs.version }}
release: ${{ steps.gh.outputs.release }}
sha: ${{ steps.gh.outputs.sha }} sha: ${{ steps.gh.outputs.sha }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with:
ref: 'openwrt'
- name: GH - name: GH
id: gh id: gh
@@ -30,7 +30,8 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash shell: bash
run: | run: |
echo "version=$(cat youtubeUnblock/Makefile | grep PKG_VERSION | sed 's/PKG_VERSION:=//')" >> $GITHUB_OUTPUT echo "version=$(cat Makefile | grep "PKG_VERSION :=" | sed 's/PKG_VERSION := //')" >> $GITHUB_OUTPUT
echo "release=$(cat Makefile | grep "PKG_RELEASE :=" | sed 's/PKG_RELEASE := //')" >> $GITHUB_OUTPUT
if [[ "${{ github.event_name }}" != "pull_request" ]]; then if [[ "${{ github.event_name }}" != "pull_request" ]]; then
echo "sha=$(echo ${GITHUB_SHA::7})" >> $GITHUB_OUTPUT echo "sha=$(echo ${GITHUB_SHA::7})" >> $GITHUB_OUTPUT
else else
@@ -72,6 +73,7 @@ jobs:
ARCH: ${{ matrix.arch }} ARCH: ${{ matrix.arch }}
CCACHE_DIR: ${{ github.workspace }}/.ccache CCACHE_DIR: ${{ github.workspace }}/.ccache
VERSION: ${{ needs.prepare.outputs.version }} VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }} SHA: ${{ needs.prepare.outputs.sha }}
shell: alpine.sh {0} shell: alpine.sh {0}
run: | run: |
@@ -85,7 +87,7 @@ jobs:
make -j$(nproc) CC="ccache gcc -static-libgcc -static" || exit 1 make -j$(nproc) CC="ccache gcc -static-libgcc -static" || exit 1
strip -s build/youtubeUnblock strip -s build/youtubeUnblock
cp -va build/youtubeUnblock . cp -va build/youtubeUnblock .
tar -czvf youtubeUnblock-$VERSION-$SHA-$PLATFORM-static.tar.gz youtubeUnblock youtubeUnblock.service README.md tar -czvf youtubeUnblock-$VERSION-$RELEASE-$SHA-$PLATFORM-static.tar.gz youtubeUnblock youtubeUnblock.service README.md
ccache --show-stats ccache --show-stats
- name: Upload artifacts - name: Upload artifacts
@@ -114,6 +116,8 @@ jobs:
tool: mips-unknown-linux-musl tool: mips-unknown-linux-musl
- arch: mipssf - arch: mipssf
tool: mips-unknown-linux-muslsf tool: mips-unknown-linux-muslsf
- arch: armv7sf
tool: armv7-unknown-linux-musleabi
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -126,7 +130,7 @@ jobs:
run: | run: |
mkdir -p $HOME/tools mkdir -p $HOME/tools
gh api repos/$REPO/releases/latest --jq '.tag_name' |\ gh api repos/$REPO/releases/latest --jq '.tag_name' |\
xargs -I{} wget -qO- https://github.com/$REPO/releases/download/{}/$TOOL.tgz | tar -C $HOME/tools -xz || exit 1 xargs -I{} wget -qO- https://github.com/$REPO/releases/download/{}/$TOOL.tar.xz | tar -C $HOME/tools -xJ || exit 1
[ -d "$HOME/tools/$TOOL/bin" ] && echo "$HOME/tools/$TOOL/bin" >> $GITHUB_PATH [ -d "$HOME/tools/$TOOL/bin" ] && echo "$HOME/tools/$TOOL/bin" >> $GITHUB_PATH
- name: Build - name: Build
@@ -135,6 +139,7 @@ jobs:
ARCH: ${{ matrix.arch }} ARCH: ${{ matrix.arch }}
TOOL: ${{ matrix.tool }} TOOL: ${{ matrix.tool }}
VERSION: ${{ needs.prepare.outputs.version }} VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }} SHA: ${{ needs.prepare.outputs.sha }}
run: | run: |
make -j$(nproc) \ make -j$(nproc) \
@@ -146,13 +151,13 @@ jobs:
CROSS_COMPILE_PLATFORM=$TOOL || exit 1 CROSS_COMPILE_PLATFORM=$TOOL || exit 1
$TOOL-strip -s build/youtubeUnblock $TOOL-strip -s build/youtubeUnblock
cp -va build/youtubeUnblock . cp -va build/youtubeUnblock .
tar -czvf youtubeUnblock-$VERSION-$SHA-$ARCH-static.tar.gz youtubeUnblock youtubeUnblock.service README.md tar -czvf youtubeUnblock-$VERSION-$RELEASE-$SHA-$ARCH-static.tar.gz youtubeUnblock youtubeUnblock.service README.md
- name: Upload artifacts - name: Upload artifacts
if: steps.build.outcome == 'success' if: steps.build.outcome == 'success'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: static-${{ matrix.arch }} name: youtubeUnblock-static-${{ matrix.arch }}
path: ./**/youtubeUnblock*.tar.gz path: ./**/youtubeUnblock*.tar.gz
build-openwrt: build-openwrt:
@@ -201,14 +206,26 @@ jobs:
- name: Prepare build - name: Prepare build
env: env:
VERSION: ${{ needs.prepare.outputs.version }} VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }} SHA: ${{ needs.prepare.outputs.sha }}
run: | run: |
sed -i "s/PKG_REV:=.*$/PKG_REV:=$SHA/;s/PKG_VERSION:=.*$/PKG_VERSION:=$VERSION-$SHA/" youtubeUnblock/Makefile sed -i "s/PKG_REV:=.*$/PKG_REV:=$SHA/;s/PKG_VERSION:=.*$/PKG_VERSION:=$VERSION-$RELEASE-$SHA/" youtubeUnblock/Makefile
- name: Initilalize SDK
id: init_sdk
env:
VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }}
working-directory: /builder
run: |
HOME=/builder ./setup.sh
- name: Build packages - name: Build packages
id: build id: build
env: env:
VERSION: ${{ needs.prepare.outputs.version }} VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }} SHA: ${{ needs.prepare.outputs.sha }}
working-directory: /builder working-directory: /builder
run: | run: |
@@ -218,7 +235,7 @@ jobs:
./scripts/feeds install -a -p youtubeUnblock ./scripts/feeds install -a -p youtubeUnblock
make defconfig make defconfig
make package/youtubeUnblock/compile V=s make package/youtubeUnblock/compile V=s
mv $(find ./bin -type f -name 'youtubeUnblock*.ipk') ./youtubeUnblock-$VERSION-$SHA-${{ matrix.arch }}-${{ matrix.branch }}.ipk mv $(find ./bin -type f -name 'youtubeUnblock*.ipk') ./youtubeUnblock-$VERSION-$RELEASE-$SHA-${{ matrix.arch }}-${{ matrix.branch }}.ipk
- name: Upload packages - name: Upload packages
if: steps.build.outcome == 'success' if: steps.build.outcome == 'success'
@@ -243,14 +260,26 @@ jobs:
- name: Prepare build - name: Prepare build
env: env:
VERSION: ${{ needs.prepare.outputs.version }} VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }} SHA: ${{ needs.prepare.outputs.sha }}
run: | run: |
sed -i "s/PKG_REV:=.*$/PKG_REV:=$SHA/;s/PKG_VERSION:=.*$/PKG_VERSION:=$VERSION-$SHA/" youtubeUnblock/Makefile sed -i "s/PKG_REV:=.*$/PKG_REV:=$SHA/;s/PKG_VERSION:=.*$/PKG_VERSION:=$VERSION-$RELEASE-$SHA/" youtubeUnblock/Makefile
- name: Initilalize SDK
id: init_sdk
env:
VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }}
working-directory: /builder
run: |
HOME=/builder ./setup.sh
- name: Build packages - name: Build packages
id: build id: build
env: env:
VERSION: ${{ needs.prepare.outputs.version }} VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }} SHA: ${{ needs.prepare.outputs.sha }}
working-directory: /builder working-directory: /builder
run: | run: |
@@ -260,7 +289,7 @@ jobs:
./scripts/feeds install -a -p youtubeUnblock ./scripts/feeds install -a -p youtubeUnblock
make defconfig make defconfig
make package/luci-app-youtubeUnblock/compile V=s make package/luci-app-youtubeUnblock/compile V=s
mv $(find ./bin -type f -name 'luci-app-youtubeUnblock*.ipk') ./luci-app-youtubeUnblock-$VERSION-$SHA.ipk mv $(find ./bin -type f -name 'luci-app-youtubeUnblock*.ipk') ./luci-app-youtubeUnblock-$VERSION-$RELEASE-$SHA.ipk
- name: Upload packages - name: Upload packages
if: steps.build.outcome == 'success' if: steps.build.outcome == 'success'
@@ -281,90 +310,53 @@ jobs:
- mips-3.4 - mips-3.4
- mipsel-3.4 - mipsel-3.4
- x64-3.2 - x64-3.2
- x86-2.6
- armv7-2.6
container:
image: waujito/entware_builder:${{ matrix.arch }}
options: --user root
steps: steps:
- name: Set up Entware docker container
run: |
git clone --depth 1 https://github.com/Entware/docker.git
docker build docker --pull --tag builder
docker volume create entware-home
- name: Restore Entware from cache
id: cache-restore
uses: actions/cache/restore@v4
with:
path: ~/entware
key: entware-${{ matrix.arch }}
- name: Load Entware from cache
if: steps.cache-restore.outputs.cache-hit == 'true'
run: |
docker run --rm --mount source=entware-home,target=/backup_vol -v ~/entware:/backup ubuntu tar -xf /backup/entware.tar -C /backup_vol
docker run --rm --mount source=entware-home,target=/home/me -w /home/me ubuntu bash -c 'cp -r ./backup_vol/* ./'
docker run --rm --mount source=entware-home,target=/home/me -w /home/me ubuntu bash -c 'chown -R 1000:1000 ./* ./'
- name: Build Entware
if: steps.cache-restore.outputs.cache-hit != 'true'
run: |
docker run --rm -i --mount source=entware-home,target=/home/me -w /home/me --name builder builder git clone --depth 1 https://github.com/Entware/Entware.git
docker run --rm -i --mount source=entware-home,target=/home/me -w /home/me/Entware --name builder builder make package/symlinks
docker run --rm -i --mount source=entware-home,target=/home/me -w /home/me/Entware --name builder builder cp -v configs/${{ matrix.arch }}.config .config
docker run --rm -i --mount source=entware-home,target=/home/me -w /home/me/Entware --name builder builder make -j$(nproc) toolchain/install
docker run --rm --mount source=entware-home,target=/backup_vol -v ~/entware:/backup ubuntu tar -cf /backup/entware.tar /backup_vol
- name: Save Entware to cache
if: steps.cache-restore.outputs.cache-hit != 'true'
id: cache-save
uses: actions/cache/save@v4
with:
path: ~/entware
key: entware-${{ matrix.arch }}
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
ref: 'entware' ref: 'openwrt'
- name: Prepare build - name: Prepare build
env: env:
VERSION: ${{ needs.prepare.outputs.version }} VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }} SHA: ${{ needs.prepare.outputs.sha }}
run: | run: |
sed -i "s/PKG_REV:=.*$/PKG_REV:=$SHA/;s/PKG_VERSION:=.*$/PKG_VERSION:=$VERSION-$SHA/" youtubeUnblock/Makefile sed -i "s/PKG_REV:=.*$/PKG_REV:=$SHA/;s/PKG_VERSION:=.*$/PKG_VERSION:=$VERSION-$RELEASE-$SHA/" youtubeUnblock/Makefile
- name: Build packages - name: Build packages
id: build id: build
run: | working-directory: /home/me/Entware
echo "src-link youtubeUnblock /youtubeUnblock" | docker run --rm -i --mount source=entware-home,target=/home/me -v $GITHUB_WORKSPACE:/youtubeUnblock -w /home/me/Entware --name builder builder tee -a feeds.conf
docker run --rm -i --mount source=entware-home,target=/home/me -v $GITHUB_WORKSPACE:/youtubeUnblock -w /home/me/Entware --name builder builder ./scripts/feeds update youtubeUnblock
docker run --rm -i --mount source=entware-home,target=/home/me -v $GITHUB_WORKSPACE:/youtubeUnblock -w /home/me/Entware --name builder builder ./scripts/feeds install -a -p youtubeUnblock
echo "CONFIG_PACKAGE_youtubeUnblock=m" | docker run --rm -i --mount source=entware-home,target=/home/me -v $GITHUB_WORKSPACE:/youtubeUnblock -w /home/me/Entware --name builder builder tee -a .config
docker run --rm -i --mount source=entware-home,target=/home/me -v $GITHUB_WORKSPACE:/youtubeUnblock -w /home/me/Entware --name builder builder make package/youtubeUnblock/compile V=s
- name: Extract packages
if: steps.build.outcome == 'success'
shell: bash
env: env:
VERSION: ${{ needs.prepare.outputs.version }} VERSION: ${{ needs.prepare.outputs.version }}
RELEASE: ${{ needs.prepare.outputs.release }}
SHA: ${{ needs.prepare.outputs.sha }} SHA: ${{ needs.prepare.outputs.sha }}
run: | run: |
mkdir output echo "src-link youtubeUnblock $GITHUB_WORKSPACE" >> feeds.conf
docker run --rm --user root -i --mount source=entware-home,target=/home/me -v $(pwd):/target -w /home/me/Entware --name builder builder find ./bin -type f -name 'youtubeUnblock*.ipk' -exec cp -v {} /target/output \; cat feeds.conf
rm -rf youtubeUnblock || true ./scripts/feeds update youtubeUnblock
mkdir youtubeUnblock ./scripts/feeds install -a -p youtubeUnblock
bash -c "cp -r ./output/* youtubeUnblock" echo "CONFIG_PACKAGE_youtubeUnblockEntware=m" | tee -a .config
tar -czvf youtubeUnblock-$VERSION-$SHA-${{ matrix.arch }}-entware.tar.gz youtubeUnblock make package/youtubeUnblockEntware/compile V=s
mv $(find ./bin -type f -name 'youtubeUnblockEntware*.ipk') ./youtubeUnblock-$VERSION-$RELEASE-$SHA-entware-${{ matrix.arch }}.ipk
- name: Upload packages - name: Upload packages
if: steps.build.outcome == 'success' if: steps.build.outcome == 'success'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: youtubeUnblock-entware-${{ matrix.arch }} name: youtubeUnblock-entware-${{ matrix.arch }}
path: ./**/youtubeUnblock*-entware.tar.gz path: /home/me/Entware/youtubeUnblock*.ipk
if-no-files-found: error if-no-files-found: error
pre-release: pre-release:
if: github.event_name != 'pull_request' && github.ref_name == 'main' if: github.event_name != 'pull_request' && github.ref_name == 'main'
needs: [build-static, build-static-cross, build-openwrt, build-entware] needs: [build-static, build-static-cross, build-openwrt, build-entware, build-openwrt-luci]
permissions: permissions:
contents: write contents: write
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@@ -1,25 +1,16 @@
# Tests whether the youtubeUnblock builds properly
name: "youtubeUnblock build test" name: "youtubeUnblock build test"
on: on:
push: push:
branches: [ "main" ] branches:
- main
paths-ignore: paths-ignore:
- '.editorconfig' - '.editorconfig'
- '.gitignore' - '.gitignore'
- 'LICENSE' - 'LICENSE'
- 'README.md' - 'README.md'
pull_request:
branches: [ "main" ]
paths-ignore:
- '.editorconfig'
- '.gitignore'
- 'LICENSE'
- 'README.md'
workflow_dispatch: workflow_dispatch:
pull_request:
jobs: jobs:
prepare: prepare:
@@ -85,104 +76,18 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
include: kernel_version:
- kernel_version: "6.6.52" - 6.6.52
source: "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.52.tar.xz" - 5.15.167
container_version: "24.04" - 5.4.284
- 4.19.322
- kernel_version: "5.15.167" - 4.4.302
source: "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.167.tar.xz" - 3.10.108
container_version: "24.04" - 3.0.101
- kernel_version: "5.4.284"
source: "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.4.284.tar.xz"
container_version: "24.04"
- kernel_version: "4.19.322"
source: "https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.19.322.tar.xz"
container_version: "24.04"
- kernel_version: "4.4.302"
source: "https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.302.tar.xz"
container_version: "24.04"
- kernel_version: "3.10.108"
source: "https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.10.108.tar.xz"
container_version: "16.04"
- kernel_version: "3.0.101"
source: "https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.0.101.tar.xz"
container_version: "14.04"
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Restore builder from cache
id: cache-restore
uses: actions/cache/restore@v4
with:
path: ~/builder.tar
key: builder-${{ matrix.kernel_version }}
- name: Load builder from cache
if: steps.cache-restore.outputs.cache-hit == 'true'
run: |
docker import - builder < ~/builder.tar
- name: Prepare build env
if: steps.cache-restore.outputs.cache-hit != 'true'
run: |
mkdir ~/linux
pwd
ls /
ls ~
- name: Obtain kernel
if: steps.cache-restore.outputs.cache-hit != 'true'
run: |
cd ~/linux
wget ${{ matrix.source }} -O kernel.tar.xz -q
tar -xf kernel.tar.xz
rm -f kernel.tar.xz
/bin/bash -c "mv linux-* linux"
ls
ls linux
- name: Install docker
if: steps.cache-restore.outputs.cache-hit != 'true'
run: |
cd ~/linux
docker pull ubuntu:${{ matrix.container_version }}
docker container create --name ubu_builder -w / ubuntu:${{ matrix.container_version }} tail -f /dev/null
docker container start ubu_builder
docker container exec ubu_builder bash -c "apt update && apt install -y build-essential flex bc bison libelf-dev elfutils libssl-dev"
docker cp ./linux ubu_builder:/linux
- name: Build kernel
if: steps.cache-restore.outputs.cache-hit != 'true'
run: |
cd ~/linux
docker container exec -w /linux ubu_builder bash -c 'make defconfig'
docker container exec -w /linux ubu_builder bash -c 'make -j $(nproc)'
- name: Export container
if: steps.cache-restore.outputs.cache-hit != 'true'
run: |
cd ~/linux
docker container kill ubu_builder
docker container export ubu_builder > ubu_builder.tar
docker container rm ubu_builder
mv ./ubu_builder.tar ~/builder.tar
docker import - builder < ~/builder.tar
- name: Save kernel image to cache
if: steps.cache-restore.outputs.cache-hit != 'true'
id: cache-save
uses: actions/cache/save@v4
with:
path: ~/builder.tar
key: builder-${{ matrix.kernel_version }}
- name: Build kernel module - name: Build kernel module
id: build id: build
env: env:
@@ -190,7 +95,7 @@ jobs:
SHA: ${{ needs.prepare.outputs.sha }} SHA: ${{ needs.prepare.outputs.sha }}
shell: bash shell: bash
run: | run: |
docker run --rm -v ./:/youtubeUnblock -w /youtubeUnblock builder make kmake KERNEL_BUILDER_MAKEDIR:=/linux docker run --rm -v ./:/youtubeUnblock -w /youtubeUnblock waujito/kernel-bins:${{ matrix.kernel_version }} make kmake KERNEL_BUILDER_MAKEDIR:=/linux
tar -czvf kmod-youtubeUnblock-$VERSION-$SHA-linux-${{ matrix.kernel_version }}.tar.gz kyoutubeUnblock.ko tar -czvf kmod-youtubeUnblock-$VERSION-$SHA-linux-${{ matrix.kernel_version }}.tar.gz kyoutubeUnblock.ko
- name: Upload artifacts - name: Upload artifacts

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule ".github/builder_containers/entware_docker"]
path = .github/builder_containers/entware_docker
url = https://github.com/Entware/docker.git

View File

@@ -1,6 +1,13 @@
USPACE_TARGETS := default all install uninstall dev run_dev USPACE_TARGETS := default all install uninstall dev run_dev
KMAKE_TARGETS := kmake kload kunload kreload xmod xtclean KMAKE_TARGETS := kmake kload kunload kreload xmod xtclean
PKG_VERSION := 1.0.0
PKG_RELEASE := 4
PKG_FULLVERSION := $(PKG_VERSION)-$(PKG_RELEASE)
export PKG_VERSION PKG_RELEASE PKG_FULLVERSION
.PHONY: $(USPACE_TARGETS) $(KMAKE_TARGETS) clean .PHONY: $(USPACE_TARGETS) $(KMAKE_TARGETS) clean
$(USPACE_TARGETS): $(USPACE_TARGETS):
@$(MAKE) -f uspace.mk $@ @$(MAKE) -f uspace.mk $@

30
Padavan.md Normal file
View File

@@ -0,0 +1,30 @@
## Padavan
На падаване есть раздел, доступный для записи (/etc/storage), и, докинув нужные модули, можно запустить youtubeUblock на уже установленной прошивке без USB. Установка самого youtubeUblock мало будет отличаться от классичкской установки. Наибольшая сложность заключается в получении модулей ядра специально для вашего роутера.
**Версия youtubeUblock должна быть не меньше v1.0.0-rc4.**
### Сборка прошивки с модулями
Необходимо собрать ядро с модулями nfqueue. Собирать можно у себя локально, а можно и в github actions (https://github.com/shvchk/padavan-builder-workflow)
Добавить строки ниже в `padavan-ng/trunk/configs/boards/TPLINK/TL_C5-V4/kernel-3.4.x.config` (вместо TPLINK/TL_C5-V4 нужно выбрать свою модель):
```sh
CONFIG_NETFILTER_NETLINK=m
CONFIG_NETFILTER_NETLINK_QUEUE=m
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
CONFIG_IP_NF_QUEUE=m
CONFIG_IP6_NF_QUEUE=m
```
Сборка
```sh
cd padavan-ng/trunk
cp configs/templates/tplink/tl_c5-v4.config .config
./build_firmware.sh
```
Если финальный размер превышает максимум, то можно отключить что-нибудь в .config, например FTP.
После сборки необходимо установить прошивку на роутер. Подробнее в гитлабе падавана: https://gitlab.com/hadzhioglu/padavan-ng. Как устанавливать: https://4pda.to/forum/index.php?showtopic=975687&st=12980#Spoil-115912586-5
Далее скачать youtubeUnblock, закинуть его на роутер, добавить правила фаервола и запустить. Можно скачивать static бинарник и запускать вручную, а можно загрузить entware на usb или в память, и поставить соответствующую версию youtubeUblock.

View File

@@ -21,6 +21,7 @@
- [Building on host system](#building-on-host-system) - [Building on host system](#building-on-host-system)
- [Building on any kernel](#building-on-any-kernel) - [Building on any kernel](#building-on-any-kernel)
- [Building with openwrt SDK](#building-with-openwrt-sdk) - [Building with openwrt SDK](#building-with-openwrt-sdk)
- [Padavan](#padavan)
# youtubeUnblock # youtubeUnblock
@@ -87,6 +88,8 @@ Now we go to the configuration. For OpenWRT here is configuration via [UCI](http
For **LuCI** aka **GUI** aka **web-interface of router** you should install **luci-app-youtubeUnblock** package like you did it with the normal youtubeUnblock package. Note, that lists of official opkg feeds should be loaded (**Do it with Update lists option**). For **LuCI** aka **GUI** aka **web-interface of router** you should install **luci-app-youtubeUnblock** package like you did it with the normal youtubeUnblock package. Note, that lists of official opkg feeds should be loaded (**Do it with Update lists option**).
If you got ` * pkg_hash_check_unresolved: cannot find dependency luci-lua-runtime for luci-app-youtubeUnblock` error, you are using old openwrt. Install [this dummy package](https://github.com/xiaorouji/openwrt-passwall/files/12605732/luci-lua-runtime_all_fake.zip). [Check this comment](https://github.com/Waujito/youtubeUnblock/issues/168#issuecomment-2449227547) for more details.
LuCI configuration lives in **Services->youtubeUnblock** section. It is self descriptive, with description for each flag. Note, that after you push `Save & Apply` button, the configuration is applied automatically and the service is restarted. LuCI configuration lives in **Services->youtubeUnblock** section. It is self descriptive, with description for each flag. Note, that after you push `Save & Apply` button, the configuration is applied automatically and the service is restarted.
UCI configuration is available in /etc/config/youtubeUnblock file, in section `youtubeUnblock.youtubeUnblock`. The configuration is done with [flags](#flags). Note, that names of flags are not the same: you should replace `-` with `_`, you shouldn't use leading `--` for flag. Also you will enable toggle flags (without parameters) with `1`. UCI configuration is available in /etc/config/youtubeUnblock file, in section `youtubeUnblock.youtubeUnblock`. The configuration is done with [flags](#flags). Note, that names of flags are not the same: you should replace `-` with `_`, you shouldn't use leading `--` for flag. Also you will enable toggle flags (without parameters) with `1`.
@@ -105,10 +108,19 @@ for example, you can enable it with `/etc/init.d/youtubeUnblock enable`.
### Entware ### Entware
For Entware on Keenetic here is an [installation guide (russian)](https://help.keenetic.com/hc/ru/articles/360021214160-%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B-%D0%BF%D0%B0%D0%BA%D0%B5%D1%82%D0%BE%D0%B2-%D1%80%D0%B5%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D1%8F-Entware-%D0%BD%D0%B0-USB-%D0%BD%D0%B0%D0%BA%D0%BE%D0%BF%D0%B8%D1%82%D0%B5%D0%BB%D1%8C). Note that if your Entware router is missing netfilter queue kernel modules, here is no way to deal with it since Entware does not offer kernel modules. For Entware on Keenetic here is an [installation guide (russian)](https://help.keenetic.com/hc/ru/articles/360021214160-%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0-%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B-%D0%BF%D0%B0%D0%BA%D0%B5%D1%82%D0%BE%D0%B2-%D1%80%D0%B5%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D1%8F-Entware-%D0%BD%D0%B0-USB-%D0%BD%D0%B0%D0%BA%D0%BE%D0%BF%D0%B8%D1%82%D0%B5%D0%BB%D1%8C).
Install the binary with `opkg install youtubeUnblock-*.ipk`. After installation, the binary in /opt/bin and the init script in /opt/etc/init.d/S51youtubeUnblock will be available. To run the youtubeUnblock, simply run `/opt/etc/init.d/S51youtubeUnblock start` Install the binary with `opkg install youtubeUnblock-*.ipk`. After installation, the binary in /opt/bin and the init script in /opt/etc/init.d/S51youtubeUnblock will be available. To run the youtubeUnblock, simply run `/opt/etc/init.d/S51youtubeUnblock start`
### NFNETLINK_QUEUE kernel modules
Note, that you should feed the target kernel with nfnetlink_queue kernel module. The module may be disabled or even not present. Entware S51youtubeUnblock will try to insert kmods any way but if they are not provided by software, you should install them manually. AFAIK on keenetics here is a repository with modules compiled by customer. You can find them somewhere in the web interface of your device. On other routers you may want to do deeper research in that case and find your kmods. If you can't find anything, you may ask the customer for GPL codes of linux kernel (and may be even OpenWRT) and compile kmods manually.
You should insert the module with (this step may be omitted on Entware and OpenWRT):
```sh
modprobe nfnetlink_queue
```
### PC configuration ### PC configuration
On local host make sure to change **FORWARD** to **OUTPUT** chain in the following Firewall rulesets. On local host make sure to change **FORWARD** to **OUTPUT** chain in the following Firewall rulesets.
@@ -175,7 +187,7 @@ Available flags:
- `--sni-domains=<comma separated domain list>|all` List of domains you want to be handled by SNI. Use this string if you want to change default domain list. Defaults to `googlevideo.com,ggpht.com,ytimg.com,youtube.com,play.google.com,youtu.be,googleapis.com,googleusercontent.com,gstatic.com,l.google.com`. You can pass **all** if you want for every *ClientHello* to be handled. You can exclude some domains with `--exclude-domains` flag. - `--sni-domains=<comma separated domain list>|all` List of domains you want to be handled by SNI. Use this string if you want to change default domain list. Defaults to `googlevideo.com,ggpht.com,ytimg.com,youtube.com,play.google.com,youtu.be,googleapis.com,googleusercontent.com,gstatic.com,l.google.com`. You can pass **all** if you want for every *ClientHello* to be handled. You can exclude some domains with `--exclude-domains` flag.
- `--exclude-domains=<comma separated domain list>` List of domains to be excluded from targetting. - `--exclude-domains=<comma separated domain list>` List of domains to be excluded from targeting.
- `--queue-num=<number of netfilter queue>` The number of netfilter queue **youtubeUnblock** will be linked to. Defaults to **537**. - `--queue-num=<number of netfilter queue>` The number of netfilter queue **youtubeUnblock** will be linked to. Defaults to **537**.
@@ -187,7 +199,7 @@ Available flags:
- `--fake-custom-payload=<payload>` Useful with `--fake-sni-type=custom`. You should specify the payload for fake message manually. Use hex format: `--fake-custom-payload=0001020304` mean that 5 bytes sequence: `0x00`, `0x01`, `0x02`, `0x03`, `0x04` used as fake. - `--fake-custom-payload=<payload>` Useful with `--fake-sni-type=custom`. You should specify the payload for fake message manually. Use hex format: `--fake-custom-payload=0001020304` mean that 5 bytes sequence: `0x00`, `0x01`, `0x02`, `0x03`, `0x04` used as fake.
- `--faking-strategy={randseq|ttl|tcp_check|pastseq|md5sum}` This flag determines the strategy of fake packets invalidation. Defaults to `randseq` - `--faking-strategy={randseq|ttl|tcp_check|pastseq|md5sum}` This flag determines the strategy of fake packets invalidation. Defaults to `randseq`
- `randseq` specifies that random sequence/acknowledgemend random will be set. This option may be handled by provider which uses *conntrack* with drop on invalid *conntrack* state firewall rule enabled. - `randseq` specifies that random sequence/acknowledgment random will be set. This option may be handled by provider which uses *conntrack* with drop on invalid *conntrack* state firewall rule enabled.
- `ttl` specifies that packet will be invalidated after `--faking-ttl=n` hops. `ttl` is better but may cause issues if unconfigured. - `ttl` specifies that packet will be invalidated after `--faking-ttl=n` hops. `ttl` is better but may cause issues if unconfigured.
- `pastseq` is like `randseq` but sequence number is not random but references the packet sent in the past (before current). - `pastseq` is like `randseq` but sequence number is not random but references the packet sent in the past (before current).
- `tcp_check` will invalidate faking packet with invalid checksum. May be handled and dropped by some providers/TSPUs. - `tcp_check` will invalidate faking packet with invalid checksum. May be handled and dropped by some providers/TSPUs.
@@ -227,7 +239,13 @@ Available flags:
- `--no-ipv6` Disables support for ipv6. May be useful if you don't want for ipv6 socket to be opened. - `--no-ipv6` Disables support for ipv6. May be useful if you don't want for ipv6 socket to be opened.
- `--threads=<threads number>` Specifies the amount of threads you want to be running for your program. This defaults to **1** and shouldn't be edited for normal use. If you have performance issues, consult [performance chaptr](https://github.com/Waujito/youtubeUnblock?tab=readme-ov-file#performance) - `--threads=<threads number>` Specifies the amount of threads you want to be running for your program. This defaults to **1** and shouldn't be edited for normal use. But if you really want multiple queue instances of youtubeUnblock, note that you should change --queue-num to --queue balance. For example, with 4 threads, use `--queue-balance 537:540` on iptables and `queue num 537-540` on nftables.
- `--daemonize` Daemonizes the youtubeUnblock (forks and detaches it from the shell). Terminate the program with `killall youtubeUnblock`. If you want to track the logs of youtubeUnblock in logread or journalctl, use **--syslog** flag.
- `--syslog` Redirects logs to the system log. You can read it with `journalctl` or `logread`.
- `--noclose` Usable only with `--daemonize`. Will not redirect io streams to /dev/null.
- `--packet-mark=<mark>` Use this option if youtubeUnblock conflicts with other systems rely on packet mark. Note that you may want to change accept rule for iptables to follow the mark. - `--packet-mark=<mark>` Use this option if youtubeUnblock conflicts with other systems rely on packet mark. Note that you may want to change accept rule for iptables to follow the mark.
@@ -242,6 +260,8 @@ If you have troubles with some sites being proxied, you can play with flags valu
If you are on Chromium you may have to disable *kyber* (the feature that makes the TLS *ClientHello* very big). I've got the problem with it on router, so to escape possible errors, so it is better to disable it: in `chrome://flags` search for kyber and switch it to disabled state. Alternatively you may set `--sni-detection=brute` and probably adjust `--sni-domains` flag. If you are on Chromium you may have to disable *kyber* (the feature that makes the TLS *ClientHello* very big). I've got the problem with it on router, so to escape possible errors, so it is better to disable it: in `chrome://flags` search for kyber and switch it to disabled state. Alternatively you may set `--sni-detection=brute` and probably adjust `--sni-domains` flag.
*Kyber* on firefox disables with `security.tls.enable_kyber` in `about:config`.
If your browser is using QUIC it may not work properly. Disable it in Chrome in `chrome://flags` and in Firefox `network.http.http{2,3}.enable(d)` in `about:config` option. If your browser is using QUIC it may not work properly. Disable it in Chrome in `chrome://flags` and in Firefox `network.http.http{2,3}.enable(d)` in `about:config` option.
It seems like some TSPUs started to block wrongseq packets, so you should play around with faking strategies. I personally recommend to start with `md5sum` faking strategy. It seems like some TSPUs started to block wrongseq packets, so you should play around with faking strategies. I personally recommend to start with `md5sum` faking strategy.
@@ -381,4 +401,11 @@ make package/kyoutubeUnblock/compile V=s
When the commands finish, the module is ready. Find it with `find bin -name "kmod-youtubeUnblock*.ipk"`, copy to your host and install to the router via gui software interface. The module should start immediately. If not, do `modprobe kyoutubeUnblock`. When the commands finish, the module is ready. Find it with `find bin -name "kmod-youtubeUnblock*.ipk"`, copy to your host and install to the router via gui software interface. The module should start immediately. If not, do `modprobe kyoutubeUnblock`.
## Padavan
YoutubeUnblock may also run on Padavan. [Check the manual here\[rus\]](Padavan.md)
>If you have any questions/suggestions/problems feel free to open an [issue](https://github.com/Waujito/youtubeUnblock/issues). >If you have any questions/suggestions/problems feel free to open an [issue](https://github.com/Waujito/youtubeUnblock/issues).

153
args.c
View File

@@ -8,6 +8,7 @@
#include <string.h> #include <string.h>
#include "types.h" #include "types.h"
#include "args.h" #include "args.h"
#include "logging.h"
static char custom_fake_buf[MAX_FAKE_SIZE]; static char custom_fake_buf[MAX_FAKE_SIZE];
@@ -21,40 +22,47 @@ struct config_t config = {
.use_gso = true, .use_gso = true,
.default_config = default_section_config, .default_config = default_section_config,
.custom_configs_len = 0 .custom_configs_len = 0,
.daemonize = 0,
.noclose = 0,
.syslog = 0,
}; };
#define OPT_SNI_DOMAINS 1 enum {
#define OPT_EXCLUDE_DOMAINS 25 OPT_SNI_DOMAINS,
#define OPT_FAKE_SNI 2 OPT_EXCLUDE_DOMAINS,
#define OPT_FAKING_TTL 3 OPT_FAKE_SNI,
#define OPT_FAKING_STRATEGY 10 OPT_FAKING_TTL,
#define OPT_FAKE_SNI_SEQ_LEN 11 OPT_FAKING_STRATEGY,
#define OPT_FAKE_SNI_TYPE 27 OPT_FAKE_SNI_SEQ_LEN,
#define OPT_FAKE_CUSTOM_PAYLOAD 28 OPT_FAKE_SNI_TYPE,
#define OPT_START_SECTION 29 OPT_FAKE_CUSTOM_PAYLOAD,
#define OPT_END_SECTION 30 OPT_START_SECTION,
#define OPT_FRAG 4 OPT_END_SECTION,
#define OPT_FRAG_SNI_REVERSE 12 OPT_DAEMONIZE,
#define OPT_FRAG_SNI_FAKED 13 OPT_NOCLOSE,
#define OPT_FRAG_MIDDLE_SNI 18 OPT_SYSLOG,
#define OPT_FRAG_SNI_POS 19 OPT_FRAG,
#define OPT_FK_WINSIZE 14 OPT_FRAG_SNI_REVERSE,
#define OPT_TRACE 15 OPT_FRAG_SNI_FAKED,
#define OPT_QUIC_DROP 16 OPT_FRAG_MIDDLE_SNI,
#define OPT_SNI_DETECTION 17 OPT_FRAG_SNI_POS,
#define OPT_NO_IPV6 20 OPT_FK_WINSIZE,
#define OPT_FAKE_SEQ_OFFSET 21 OPT_TRACE,
#define OPT_PACKET_MARK 22 OPT_QUIC_DROP,
#define OPT_SYNFAKE 23 OPT_SNI_DETECTION,
#define OPT_SYNFAKE_LEN 24 OPT_NO_IPV6,
#define OPT_SEG2DELAY 5 OPT_FAKE_SEQ_OFFSET,
#define OPT_THREADS 6 OPT_PACKET_MARK,
#define OPT_SILENT 7 OPT_SYNFAKE,
#define OPT_NO_GSO 8 OPT_SYNFAKE_LEN,
#define OPT_QUEUE_NUM 9 OPT_SEG2DELAY,
OPT_THREADS,
#define OPT_MAX OPT_END_SECTION OPT_SILENT,
OPT_NO_GSO,
OPT_QUEUE_NUM,
};
static struct option long_opt[] = { static struct option long_opt[] = {
{"help", 0, 0, 'h'}, {"help", 0, 0, 'h'},
@@ -84,6 +92,9 @@ static struct option long_opt[] = {
{"trace", 0, 0, OPT_TRACE}, {"trace", 0, 0, OPT_TRACE},
{"no-gso", 0, 0, OPT_NO_GSO}, {"no-gso", 0, 0, OPT_NO_GSO},
{"no-ipv6", 0, 0, OPT_NO_IPV6}, {"no-ipv6", 0, 0, OPT_NO_IPV6},
{"daemonize", 0, 0, OPT_DAEMONIZE},
{"noclose", 0, 0, OPT_NOCLOSE},
{"syslog", 0, 0, OPT_SYSLOG},
{"queue-num", 1, 0, OPT_QUEUE_NUM}, {"queue-num", 1, 0, OPT_QUEUE_NUM},
{"packet-mark", 1, 0, OPT_PACKET_MARK}, {"packet-mark", 1, 0, OPT_PACKET_MARK},
{"fbegin", 0, 0, OPT_START_SECTION}, {"fbegin", 0, 0, OPT_START_SECTION},
@@ -110,8 +121,13 @@ static long parse_numeric_option(const char* value) {
} }
void print_version() { void print_version() {
printf("youtubeUnblock\n"); printf("youtubeUnblock"
printf("Bypasses deep packet inspection systems that relies on SNI\n"); #if defined(PKG_VERSION)
" " PKG_VERSION
#endif
"\n"
);
printf("Bypasses deep packet inspection systems that rely on SNI\n");
printf("\n"); printf("\n");
} }
@@ -147,6 +163,9 @@ void print_usage(const char *argv0) {
printf("\t--trace\n"); printf("\t--trace\n");
printf("\t--no-gso\n"); printf("\t--no-gso\n");
printf("\t--no-ipv6\n"); printf("\t--no-ipv6\n");
printf("\t--daemonize\n");
printf("\t--noclose\n");
printf("\t--syslog\n");
printf("\t--fbegin\n"); printf("\t--fbegin\n");
printf("\t--fend\n"); printf("\t--fend\n");
printf("\n"); printf("\n");
@@ -197,6 +216,15 @@ int parse_args(int argc, char *argv[]) {
config.use_ipv6 = 0; config.use_ipv6 = 0;
break; break;
case OPT_DAEMONIZE:
config.daemonize = 1;
break;
case OPT_NOCLOSE:
config.noclose = 1;
break;
case OPT_SYSLOG:
config.syslog = 1;
break;
case OPT_THREADS: case OPT_THREADS:
if (section_iter != SECT_ITER_DEFAULT) if (section_iter != SECT_ITER_DEFAULT)
goto invalid_opt; goto invalid_opt;
@@ -466,96 +494,99 @@ error:
} }
void print_welcome() { void print_welcome() {
if (config.syslog) {
printf("Logging to system log\n");
}
if (config.use_gso) { if (config.use_gso) {
printf("GSO is enabled\n"); lginfo("GSO is enabled\n");
} }
if (config.use_ipv6) { if (config.use_ipv6) {
printf("IPv6 is enabled\n"); lginfo("IPv6 is enabled\n");
} else { } else {
printf("IPv6 is disabled\n"); lginfo("IPv6 is disabled\n");
} }
printf("Detected %d config sections\n", config.custom_configs_len + 1); lginfo("Detected %d config sections\n", config.custom_configs_len + 1);
printf("The sections will be processed in ordred they goes in this output"); lginfo("The sections will be processed in order they goes in this output\n");
ITER_CONFIG_SECTIONS(section) { ITER_CONFIG_SECTIONS(section) {
int section_number = CONFIG_SECTION_NUMBER(section); int section_number = CONFIG_SECTION_NUMBER(section);
printf("Section #%d\n", section_number); lginfo("Section #%d\n", section_number);
switch (section->fragmentation_strategy) { switch (section->fragmentation_strategy) {
case FRAG_STRAT_TCP: case FRAG_STRAT_TCP:
printf("Using TCP segmentation\n"); lginfo("Using TCP segmentation\n");
break; break;
case FRAG_STRAT_IP: case FRAG_STRAT_IP:
printf("Using IP fragmentation\n"); lginfo("Using IP fragmentation\n");
break; break;
default: default:
printf("SNI fragmentation is disabled\n"); lginfo("SNI fragmentation is disabled\n");
break; break;
} }
if (section->seg2_delay) { if (section->seg2_delay) {
printf("Some outgoing googlevideo request segments will be delayed for %d ms as of seg2_delay define\n", section->seg2_delay); lginfo("Some outgoing googlevideo request segments will be delayed for %d ms as of seg2_delay define\n", section->seg2_delay);
} }
if (section->fake_sni) { if (section->fake_sni) {
printf("Fake SNI will be sent before each target client hello\n"); lginfo("Fake SNI will be sent before each target client hello\n");
} else { } else {
printf("Fake SNI is disabled\n"); lginfo("Fake SNI is disabled\n");
} }
if (section->frag_sni_reverse) { if (section->frag_sni_reverse) {
printf("Fragmentation Client Hello will be reversed\n"); lginfo("Fragmentation Client Hello will be reversed\n");
} }
if (section->frag_sni_faked) { if (section->frag_sni_faked) {
printf("Fooling packets will be sent near the original Client Hello\n"); lginfo("Fooling packets will be sent near the original Client Hello\n");
} }
if (section->fake_sni_seq_len > 1) { if (section->fake_sni_seq_len > 1) {
printf("Faking sequence of length %d will be built as fake sni\n", section->fake_sni_seq_len); lginfo("Faking sequence of length %d will be built as fake sni\n", section->fake_sni_seq_len);
} }
switch (section->faking_strategy) { switch (section->faking_strategy) {
case FAKE_STRAT_TTL: case FAKE_STRAT_TTL:
printf("TTL faking strategy will be used with TTL %d\n", section->faking_ttl); lginfo("TTL faking strategy will be used with TTL %d\n", section->faking_ttl);
break; break;
case FAKE_STRAT_RAND_SEQ: case FAKE_STRAT_RAND_SEQ:
printf("Random seq faking strategy will be used\n"); lginfo("Random seq faking strategy will be used\n");
printf("Fake seq offset set to %u\n", section->fakeseq_offset); lginfo("Fake seq offset set to %u\n", section->fakeseq_offset);
break; break;
case FAKE_STRAT_TCP_CHECK: case FAKE_STRAT_TCP_CHECK:
printf("TCP checksum faking strategy will be used\n"); lginfo("TCP checksum faking strategy will be used\n");
break; break;
case FAKE_STRAT_PAST_SEQ: case FAKE_STRAT_PAST_SEQ:
printf("Past seq faking strategy will be used\n"); lginfo("Past seq faking strategy will be used\n");
break; break;
case FAKE_STRAT_TCP_MD5SUM: case FAKE_STRAT_TCP_MD5SUM:
printf("md5sum faking strategy will be used\n"); lginfo("md5sum faking strategy will be used\n");
break; break;
} }
if (section->fk_winsize) { if (section->fk_winsize) {
printf("Response TCP window will be set to %d with the appropriate scale\n", section->fk_winsize); lginfo("Response TCP window will be set to %d with the appropriate scale\n", section->fk_winsize);
} }
if (section->synfake) { if (section->synfake) {
printf("Fake SYN payload will be sent with each TCP request SYN packet\n"); lginfo("Fake SYN payload will be sent with each TCP request SYN packet\n");
} }
if (section->quic_drop) { if (section->quic_drop) {
printf("All QUIC packets will be dropped\n"); lginfo("All QUIC packets will be dropped\n");
} }
if (section->sni_detection == SNI_DETECTION_BRUTE) { if (section->sni_detection == SNI_DETECTION_BRUTE) {
printf("Server Name Extension will be parsed in the bruteforce mode\n"); lginfo("Server Name Extension will be parsed in the bruteforce mode\n");
} }
if (section->all_domains) { if (section->all_domains) {
printf("All Client Hello will be targetted by youtubeUnblock!\n"); lginfo("All Client Hello will be targeted by youtubeUnblock!\n");
} else { } else {
printf("Target sni domains: %s\n", section->domains_str); lginfo("Target sni domains: %s\n", section->domains_str);
} }
} }
} }

View File

@@ -64,7 +64,6 @@ struct section_config_t {
#define SNI_DETECTION_BRUTE 1 #define SNI_DETECTION_BRUTE 1
int sni_detection; int sni_detection;
}; };
#define MAX_CONFIGLIST_LEN 64 #define MAX_CONFIGLIST_LEN 64
@@ -75,6 +74,10 @@ struct config_t {
int use_gso; int use_gso;
int use_ipv6; int use_ipv6;
unsigned int mark; unsigned int mark;
int daemonize;
// Same as daemon() noclose
int noclose;
int syslog;
#define VERBOSE_INFO 0 #define VERBOSE_INFO 0
#define VERBOSE_DEBUG 1 #define VERBOSE_DEBUG 1
@@ -185,7 +188,7 @@ if ((fake_bitmask) & strategy)
// The Maximum Transmission Unit size for rawsocket // The Maximum Transmission Unit size for rawsocket
// Larger packets will be fragmented. Applicable for Chrome's kyber. // Larger packets will be fragmented. Applicable for Chrome's kyber.
#define AVAILABLE_MTU 1500 #define AVAILABLE_MTU 1400
#define DEFAULT_QUEUE_NUM 537 #define DEFAULT_QUEUE_NUM 537

View File

@@ -13,7 +13,7 @@ KERNEL_BUILDER_MAKEDIR:=/lib/modules/$(shell uname -r)/build
kmake: kmod kmake: kmod
kmod: kmod:
$(MAKE) -C $(KERNEL_BUILDER_MAKEDIR) M=$(PWD) modules $(MAKE) -C $(KERNEL_BUILDER_MAKEDIR) M=$(PWD) EXTRA_CFLAGS='-DPKG_VERSION=\"$(PKG_FULLVERSION)\"' modules
kload: kload:
insmod kyoutubeUnblock.ko insmod kyoutubeUnblock.ko

View File

@@ -21,8 +21,11 @@
#include "utils.h" #include "utils.h"
#include "logging.h" #include "logging.h"
#if defined(PKG_VERSION)
MODULE_VERSION(PKG_VERSION);
#endif
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_VERSION("0.3.2");
MODULE_AUTHOR("Vadim Vetrov <vetrovvd@gmail.com>"); MODULE_AUTHOR("Vadim Vetrov <vetrovvd@gmail.com>");
MODULE_DESCRIPTION("Linux kernel module for youtubeUnblock"); MODULE_DESCRIPTION("Linux kernel module for youtubeUnblock");
@@ -35,7 +38,7 @@ static int open_raw_socket(void) {
ret = sock_create(AF_INET, SOCK_RAW, IPPROTO_RAW, &rawsocket); ret = sock_create(AF_INET, SOCK_RAW, IPPROTO_RAW, &rawsocket);
if (ret < 0) { if (ret < 0) {
pr_alert("Unable to create raw socket\n"); lgerror(ret, "Unable to create raw socket\n");
goto err; goto err;
} }
@@ -80,7 +83,7 @@ static int send_raw_ipv4(const uint8_t *pkt, uint32_t pktlen) {
iov.iov_base = (__u8 *)pkt; iov.iov_base = (__u8 *)pkt;
iov.iov_len = pktlen; iov.iov_len = pktlen;
msg.msg_flags = 0; msg.msg_flags = MSG_DONTWAIT;
msg.msg_name = &daddr; msg.msg_name = &daddr;
msg.msg_namelen = sizeof(struct sockaddr_in); msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_control = NULL; msg.msg_control = NULL;
@@ -97,7 +100,7 @@ static int open_raw6_socket(void) {
ret = sock_create(AF_INET6, SOCK_RAW, IPPROTO_RAW, &raw6socket); ret = sock_create(AF_INET6, SOCK_RAW, IPPROTO_RAW, &raw6socket);
if (ret < 0) { if (ret < 0) {
pr_alert("Unable to create raw socket\n"); lgerror(ret, "Unable to create raw socket\n");
goto err; goto err;
} }
@@ -140,7 +143,7 @@ static int send_raw_ipv6(const uint8_t *pkt, uint32_t pktlen) {
iov.iov_base = (__u8 *)pkt; iov.iov_base = (__u8 *)pkt;
iov.iov_len = pktlen; iov.iov_len = pktlen;
msg.msg_flags = 0; msg.msg_flags = MSG_DONTWAIT;
msg.msg_name = &daddr; msg.msg_name = &daddr;
msg.msg_namelen = sizeof(struct sockaddr_in6); msg.msg_namelen = sizeof(struct sockaddr_in6);
msg.msg_control = NULL; msg.msg_control = NULL;
@@ -159,12 +162,12 @@ static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
NETBUF_ALLOC(buff1, MAX_PACKET_SIZE); NETBUF_ALLOC(buff1, MAX_PACKET_SIZE);
if (!NETBUF_CHECK(buff1)) { if (!NETBUF_CHECK(buff1)) {
lgerror("Allocation error", -ENOMEM); lgerror(-ENOMEM, "Allocation error");
return -ENOMEM; return -ENOMEM;
} }
NETBUF_ALLOC(buff2, MAX_PACKET_SIZE); NETBUF_ALLOC(buff2, MAX_PACKET_SIZE);
if (!NETBUF_CHECK(buff2)) { if (!NETBUF_CHECK(buff2)) {
lgerror("Allocation error", -ENOMEM); lgerror(-ENOMEM, "Allocation error");
NETBUF_FREE(buff2); NETBUF_FREE(buff2);
return -ENOMEM; return -ENOMEM;
} }
@@ -216,7 +219,7 @@ erret_lc:
} }
static int delay_packet_send(const unsigned char *data, unsigned int data_len, unsigned int delay_ms) { static int delay_packet_send(const unsigned char *data, unsigned int data_len, unsigned int delay_ms) {
pr_info("delay_packet_send won't work on current youtubeUnblock version"); lginfo("delay_packet_send won't work on current youtubeUnblock version");
return send_raw_socket(data, data_len); return send_raw_socket(data, data_len);
} }
@@ -306,7 +309,7 @@ static NF_CALLBACK(ykb_nf_hook, skb) {
ret = skb_linearize(skb); ret = skb_linearize(skb);
if (ret < 0) { if (ret < 0) {
lgerror("Cannot linearize", ret); lgerror(ret, "Cannot linearize");
goto accept; goto accept;
} }
@@ -347,41 +350,51 @@ static int __init ykb_init(void) {
ret = open_raw_socket(); ret = open_raw_socket();
if (ret < 0) goto err; if (ret < 0) goto err;
if (config.use_ipv6) {
ret = open_raw6_socket();
if (ret < 0) goto close_rawsocket;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
struct net *n;
for_each_net(n) {
ret = nf_register_net_hook(n, &ykb6_nf_reg);
if (ret < 0)
lgerror("bad rat",ret);
}
#else
nf_register_hook(&ykb6_nf_reg);
#endif
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
struct net *n; struct net *n;
for_each_net(n) { for_each_net(n) {
ret = nf_register_net_hook(n, &ykb_nf_reg); ret = nf_register_net_hook(n, &ykb_nf_reg);
if (ret < 0) if (ret < 0) {
lgerror("bad rat",ret); lgerror(ret, "register net_hook");
}
} }
#else #else
nf_register_hook(&ykb_nf_reg); ret = nf_register_hook(&ykb_nf_reg);
if (ret < 0) {
lgerror(ret, "register net_hook");
}
#endif #endif
pr_info("youtubeUnblock kernel module started.\n");
if (config.use_ipv6) {
ret = open_raw6_socket();
if (ret < 0) {
config.use_ipv6 = 0;
lgwarning("ipv6 disabled!");
goto ipv6_fallback;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
struct net *n;
for_each_net(n) {
ret = nf_register_net_hook(n, &ykb6_nf_reg);
if (ret < 0) {
lgerror(ret, "register net6_hook");
}
}
#else
ret = nf_register_hook(&ykb6_nf_reg);
if (ret < 0) {
lgerror(ret, "register net6_hook");
}
#endif
}
ipv6_fallback:
lginfo("youtubeUnblock kernel module started.\n");
return 0; return 0;
close_rawsocket:
close_raw_socket();
err: err:
return ret; return ret;
} }
@@ -407,7 +420,7 @@ static void __exit ykb_destroy(void) {
#endif #endif
close_raw_socket(); close_raw_socket();
pr_info("youtubeUnblock kernel module destroyed.\n"); lginfo("youtubeUnblock kernel module destroyed.\n");
} }
module_init(ykb_init); module_init(ykb_init);

View File

@@ -9,36 +9,62 @@
#include <linux/module.h> #include <linux/module.h>
#define printf pr_info #define printf pr_info
#define perror pr_err #define perror pr_err
#define lgerror(msg, ret, ...) __extension__ ({ \
pr_err(msg ": %d\n", ##__VA_ARGS__, ret); \ #define LOG_ERR KERN_ERR
}) #define LOG_INFO KERN_INFO
#define LOG_WARN KERN_WARNING
#define log_message(level, msg, ...) \
(printk(level msg, ##__VA_ARGS__))
#define lgerror(ret, msg, ...) \
(log_message(LOG_ERR, msg ": %d\n", ##__VA_ARGS__, ret))
#else #else
#include <stdio.h> // IWYU pragma: export #include <stdio.h> // IWYU pragma: export
#include <errno.h> #include <errno.h>
#define lgerror(msg, ret, ...) __extension__ ({ \ #include <syslog.h>
#define log_message(level, msg, ...) \
(config.syslog ? (void)(syslog((level), msg, ##__VA_ARGS__)) : (void)(printf(msg, ##__VA_ARGS__)))
#define lgerror(ret, msg, ...) __extension__ ({ \
errno = -(ret); \ errno = -(ret); \
printf(msg ": %s\n", ##__VA_ARGS__, strerror(errno)); \ log_message(LOG_ERR, msg ": %s\n", ##__VA_ARGS__, strerror(errno)); \
}) })
#endif /* PROGRAM_SPACE */ #endif /* PROGRAM_SPACE */
#define lgerr(msg, ...) \
(log_message(LOG_ERR, msg, ##__VA_ARGS__))
#define lgwarning(msg, ...) \
(log_message(LOG_WARN, msg, ##__VA_ARGS__))
#define lginfo(msg, ...) \
(log_message(LOG_INFO, msg, ##__VA_ARGS__))
#define print_message(...) \
(lginfo(__VA_ARGS__))
#define lgdebug(msg, ...) \ #define lgdebug(msg, ...) \
(LOG_LEVEL >= VERBOSE_DEBUG ? printf(msg, ##__VA_ARGS__) : 0) (LOG_LEVEL >= VERBOSE_DEBUG ? log_message(LOG_INFO, msg, ##__VA_ARGS__) : (void)0)
#define lgdebugmsg(msg, ...) lgdebug(msg "\n", ##__VA_ARGS__) #define lgdebugmsg(msg, ...) lgdebug(msg "\n", ##__VA_ARGS__)
#define lgtrace(msg, ...) \ #define lgtrace(msg, ...) \
(LOG_LEVEL >= VERBOSE_TRACE ? printf(msg, ##__VA_ARGS__) : 0) (LOG_LEVEL >= VERBOSE_TRACE ? log_message(LOG_INFO, msg, ##__VA_ARGS__) : (void)0)
#define lgtracemsg(msg, ...) lgtrace(msg "\n", __VA_ARGS__) #define lgtracemsg(msg, ...) lgtrace(msg "\n", __VA_ARGS__)
#define lgtrace_start(msg, ...) \ #define lgtrace_start(msg, ...) \
(LOG_LEVEL >= VERBOSE_TRACE ? printf("[TRACE] " msg " ( ", ##__VA_ARGS__) : 0) (LOG_LEVEL >= VERBOSE_TRACE ? log_message(LOG_INFO, "[TRACE] " msg " ( ", ##__VA_ARGS__) : (void)0)
#define lgtrace_addp(msg, ...) \ #define lgtrace_addp(msg, ...) \
(LOG_LEVEL >= VERBOSE_TRACE ? printf(msg", ", ##__VA_ARGS__) : 0) (LOG_LEVEL >= VERBOSE_TRACE ? log_message(LOG_INFO, msg", ", ##__VA_ARGS__) : (void)0)
#define lgtrace_end() \ #define lgtrace_end() \
(LOG_LEVEL >= VERBOSE_TRACE ? printf(") \n") : 0) (LOG_LEVEL >= VERBOSE_TRACE ? log_message(LOG_INFO, ") \n") : (void)0)
#endif /* LOGGING_H */ #endif /* LOGGING_H */

View File

@@ -112,7 +112,7 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
NETBUF_ALLOC(payload, MAX_PACKET_SIZE); NETBUF_ALLOC(payload, MAX_PACKET_SIZE);
if (!NETBUF_CHECK(payload)) { if (!NETBUF_CHECK(payload)) {
lgerror("Allocation error", -ENOMEM); lgerror(-ENOMEM, "Allocation error");
goto accept; goto accept;
} }
@@ -142,7 +142,7 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
ret = instance_config.send_raw_packet(payload, iph_len + tcph_len + fake_len); ret = instance_config.send_raw_packet(payload, iph_len + tcph_len + fake_len);
if (ret < 0) { if (ret < 0) {
lgerror("send_syn_altered", ret); lgerror(ret, "send_syn_altered");
NETBUF_FREE(payload); NETBUF_FREE(payload);
goto accept; goto accept;
@@ -167,7 +167,7 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
uint32_t payload_len = raw_payload_len; uint32_t payload_len = raw_payload_len;
NETBUF_ALLOC(payload, MAX_PACKET_SIZE); NETBUF_ALLOC(payload, MAX_PACKET_SIZE);
if (!NETBUF_CHECK(payload)) { if (!NETBUF_CHECK(payload)) {
lgerror("Allocation error", -ENOMEM); lgerror(-ENOMEM, "Allocation error");
goto accept; goto accept;
} }
@@ -185,7 +185,7 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
&data, &dlen); &data, &dlen);
if (ret < 0) { if (ret < 0) {
lgerror("tcp_payload_split in targ_sni", ret); lgerror(ret, "tcp_payload_split in targ_sni");
goto accept_lc; goto accept_lc;
} }
@@ -201,7 +201,7 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
&iph, &iph_len, &tcph, &tcph_len, &iph, &iph_len, &tcph, &tcph_len,
&data, &dlen); &data, &dlen);
if (ret < 0) { if (ret < 0) {
lgerror("seqovl_packet delta %d", ret, delta); lgerror(ret, "seqovl_packet delta %d", delta);
} }
} }
@@ -241,7 +241,7 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
ret = send_tcp_frags(section, payload, payload_len, poses, cnt, 0); ret = send_tcp_frags(section, payload, payload_len, poses, cnt, 0);
if (ret < 0) { if (ret < 0) {
lgerror("tcp4 send frags", ret); lgerror(ret, "tcp4 send frags");
goto accept_lc; goto accept_lc;
} }
@@ -275,20 +275,20 @@ int process_tcp_packet(const struct section_config_t *section, const uint8_t *ra
ret = send_ip4_frags(section, payload, payload_len, poses, cnt, 0); ret = send_ip4_frags(section, payload, payload_len, poses, cnt, 0);
if (ret < 0) { if (ret < 0) {
lgerror("ip4 send frags", ret); lgerror(ret, "ip4 send frags");
goto accept_lc; goto accept_lc;
} }
goto drop_lc; goto drop_lc;
} else { } else {
printf("WARNING: IP fragmentation is supported only for IPv4\n"); lginfo("WARNING: IP fragmentation is supported only for IPv4\n");
goto default_send; goto default_send;
} }
default: default:
default_send: default_send:
ret = instance_config.send_raw_packet(payload, payload_len); ret = instance_config.send_raw_packet(payload, payload_len);
if (ret < 0) { if (ret < 0) {
lgerror("raw pack send", ret); lgerror(ret, "raw pack send");
goto accept_lc; goto accept_lc;
} }
@@ -338,12 +338,15 @@ int process_udp_packet(const struct section_config_t *section, const uint8_t *pk
goto accept; goto accept;
} }
if (dlen > 10 && config.verbose >= VERBOSE_TRACE) { if (dlen > 10 && config.verbose == VERBOSE_TRACE) {
printf("UDP payload start: [ "); char logging_buf[128];
char *bufpt = logging_buf;
bufpt += sprintf(bufpt, "UDP payload start: [ ");
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
printf("%02x ", data[i]); bufpt += sprintf(bufpt, "%02x ", data[i]);
} }
printf("], "); bufpt += sprintf(bufpt, "]");
lgtrace_addp("%s", logging_buf);
} }
@@ -405,7 +408,7 @@ int process_udp_packet(const struct section_config_t *section, const uint8_t *pk
goto drop; goto drop;
} else { } else {
printf("WARNING: IP fragmentation is supported only for IPv4\n"); lginfo("WARNING: IP fragmentation is supported only for IPv4\n");
goto accept; goto accept;
} }
} }
@@ -442,20 +445,20 @@ int send_ip4_frags(const struct section_config_t *section, const uint8_t *packet
} else { } else {
NETBUF_ALLOC(frag1, MAX_PACKET_SIZE); NETBUF_ALLOC(frag1, MAX_PACKET_SIZE);
if (!NETBUF_CHECK(frag1)) { if (!NETBUF_CHECK(frag1)) {
lgerror("Allocation error", -ENOMEM); lgerror(-ENOMEM, "Allocation error");
return -ENOMEM; return -ENOMEM;
} }
NETBUF_ALLOC(frag2, MAX_PACKET_SIZE); NETBUF_ALLOC(frag2, MAX_PACKET_SIZE);
if (!NETBUF_CHECK(frag2)) { if (!NETBUF_CHECK(frag2)) {
lgerror("Allocation error", -ENOMEM); lgerror(-ENOMEM, "Allocation error");
NETBUF_FREE(frag1); NETBUF_FREE(frag1);
return -ENOMEM; return -ENOMEM;
} }
NETBUF_ALLOC(fake_pad, MAX_PACKET_SIZE); NETBUF_ALLOC(fake_pad, MAX_PACKET_SIZE);
if (!NETBUF_CHECK(fake_pad)) { if (!NETBUF_CHECK(fake_pad)) {
lgerror("Allocation error", -ENOMEM); lgerror(-ENOMEM, "Allocation error");
NETBUF_FREE(frag1); NETBUF_FREE(frag1);
NETBUF_FREE(frag2); NETBUF_FREE(frag2);
return -ENOMEM; return -ENOMEM;
@@ -468,7 +471,7 @@ int send_ip4_frags(const struct section_config_t *section, const uint8_t *packet
int ret; int ret;
if (dvs > poses[0]) { if (dvs > poses[0]) {
lgerror("send_frags: Recursive dvs(%d) is more than poses0(%d)", -EINVAL, dvs, poses[0]); lgerror(-EINVAL, "send_frags: Recursive dvs(%d) is more than poses0(%d)", dvs, poses[0]);
ret = -EINVAL; ret = -EINVAL;
goto erret_lc; goto erret_lc;
} }
@@ -480,7 +483,7 @@ int send_ip4_frags(const struct section_config_t *section, const uint8_t *packet
frag1, &f1len, frag2, &f2len); frag1, &f1len, frag2, &f2len);
if (ret < 0) { if (ret < 0) {
lgerror("send_frags: frag: with context packet with size %d, position: %d, recursive dvs: %d", ret, pktlen, poses[0], dvs); lgerror(ret, "send_frags: frag: with context packet with size %d, position: %d, recursive dvs: %d", pktlen, poses[0], dvs);
goto erret_lc; goto erret_lc;
} }
@@ -571,13 +574,13 @@ int send_tcp_frags(const struct section_config_t *section, const uint8_t *packet
} else { } else {
NETBUF_ALLOC(frag1, MAX_PACKET_SIZE); NETBUF_ALLOC(frag1, MAX_PACKET_SIZE);
if (!NETBUF_CHECK(frag1)) { if (!NETBUF_CHECK(frag1)) {
lgerror("Allocation error", -ENOMEM); lgerror(-ENOMEM, "Allocation error");
return -ENOMEM; return -ENOMEM;
} }
NETBUF_ALLOC(frag2, MAX_PACKET_SIZE); NETBUF_ALLOC(frag2, MAX_PACKET_SIZE);
if (!NETBUF_CHECK(frag2)) { if (!NETBUF_CHECK(frag2)) {
lgerror("Allocation error", -ENOMEM); lgerror(-ENOMEM, "Allocation error");
NETBUF_FREE(frag1); NETBUF_FREE(frag1);
return -ENOMEM; return -ENOMEM;
} }
@@ -588,7 +591,7 @@ int send_tcp_frags(const struct section_config_t *section, const uint8_t *packet
int ret; int ret;
if (dvs > poses[0]) { if (dvs > poses[0]) {
lgerror("send_frags: Recursive dvs(%d) is more than poses0(%d)", -EINVAL, dvs, poses[0]); lgerror(-EINVAL, "send_frags: Recursive dvs(%d) is more than poses0(%d)", dvs, poses[0]);
ret = -EINVAL; ret = -EINVAL;
goto erret_lc; goto erret_lc;
} }
@@ -601,7 +604,7 @@ int send_tcp_frags(const struct section_config_t *section, const uint8_t *packet
lgtrace_addp("Packet split in %d bytes position of payload start, dvs: %d to two packets of %d and %d lengths", poses[0], dvs, f1len, f2len); lgtrace_addp("Packet split in %d bytes position of payload start, dvs: %d to two packets of %d and %d lengths", poses[0], dvs, f1len, f2len);
if (ret < 0) { if (ret < 0) {
lgerror("send_frags: tcp_frag: with context packet with size %d, position: %d, recursive dvs: %d", ret, pktlen, poses[0], dvs); lgerror(ret, "send_frags: tcp_frag: with context packet with size %d, position: %d, recursive dvs: %d", pktlen, poses[0], dvs);
goto erret_lc; goto erret_lc;
} }
@@ -690,7 +693,7 @@ int post_fake_sni(struct fake_type f_type,
for (int i = 0; i < fake_seq_type.sequence_len; i++) { for (int i = 0; i < fake_seq_type.sequence_len; i++) {
NETBUF_ALLOC(fake_sni, MAX_PACKET_SIZE); NETBUF_ALLOC(fake_sni, MAX_PACKET_SIZE);
if (!NETBUF_CHECK(fake_sni)) { if (!NETBUF_CHECK(fake_sni)) {
lgerror("Allocation error", -ENOMEM); lgerror(-ENOMEM, "Allocation error");
return -ENOMEM; return -ENOMEM;
} }
uint32_t fsn_len = MAX_PACKET_SIZE; uint32_t fsn_len = MAX_PACKET_SIZE;
@@ -700,7 +703,7 @@ int post_fake_sni(struct fake_type f_type,
fsiph, iph_len, fstcph, tcph_len, fsiph, iph_len, fstcph, tcph_len,
fake_sni, &fsn_len); fake_sni, &fsn_len);
if (ret < 0) { if (ret < 0) {
lgerror("gen_fake_sni", ret); lgerror(ret, "gen_fake_sni");
goto erret_lc; goto erret_lc;
} }
@@ -712,7 +715,7 @@ int post_fake_sni(struct fake_type f_type,
ret = instance_config.send_raw_packet(fake_sni, fsn_len); ret = instance_config.send_raw_packet(fake_sni, fsn_len);
} }
if (ret < 0) { if (ret < 0) {
lgerror("send fake sni", ret); lgerror(ret, "send fake sni");
goto erret_lc; goto erret_lc;
} }
uint32_t iph_len; uint32_t iph_len;

2
quic.c
View File

@@ -135,6 +135,6 @@ int quic_parse_initial_message(uint8_t *inpayload, uint32_t inplen,
return 0; return 0;
invalid_packet: invalid_packet:
lgerror("QUIC invalid Initial packet", -EINVAL); lgerror(-EINVAL, "QUIC invalid Initial packet");
return -EINVAL; return -EINVAL;
} }

6
tls.c
View File

@@ -228,12 +228,12 @@ brute:
NETBUF_ALLOC(buf, MAX_PACKET_SIZE); NETBUF_ALLOC(buf, MAX_PACKET_SIZE);
if (!NETBUF_CHECK(buf)) { if (!NETBUF_CHECK(buf)) {
lgerror("Allocation error", -ENOMEM); lgerror(-ENOMEM, "Allocation error");
goto out; goto out;
} }
NETBUF_ALLOC(nzbuf, MAX_PACKET_SIZE * sizeof(int)); NETBUF_ALLOC(nzbuf, MAX_PACKET_SIZE * sizeof(int));
if (!NETBUF_CHECK(nzbuf)) { if (!NETBUF_CHECK(nzbuf)) {
lgerror("Allocation error", -ENOMEM); lgerror(-ENOMEM, "Allocation error");
NETBUF_FREE(buf); NETBUF_FREE(buf);
goto out; goto out;
} }
@@ -324,7 +324,7 @@ int gen_fake_sni(struct fake_type type,
#if _NO_GETRANDOM #if _NO_GETRANDOM
ret = open("/dev/urandom", O_RDONLY); ret = open("/dev/urandom", O_RDONLY);
if (ret < 0) { if (ret < 0) {
lgerror("Unable to open /dev/urandom", ret); lgerror(ret, "Unable to open /dev/urandom");
return ret; return ret;
} }

View File

@@ -85,6 +85,9 @@
#endif /* not a KERNEL_SPACE */ #endif /* not a KERNEL_SPACE */
/* An alternative memory allocation strategy for userspace app */
// #define ALLOC_MALLOC
/** /**
* Use NETBUF_ALLOC and NETBUF_FREE as an abstraction of memory allocation. * Use NETBUF_ALLOC and NETBUF_FREE as an abstraction of memory allocation.
* Do not use it within expressions, consider these defines as separate statements. * Do not use it within expressions, consider these defines as separate statements.

View File

@@ -10,13 +10,13 @@ CCLD:=$(CC)
LD:=ld LD:=ld
ifeq ($(USE_SYS_LIBS), no) ifeq ($(USE_SYS_LIBS), no)
override CFLAGS += -Wall -Wpedantic -Wno-unused-variable -I$(DEPSDIR)/include -std=gnu11 override CFLAGS += -I$(DEPSDIR)/include
override LDFLAGS += -L$(DEPSDIR)/lib override LDFLAGS += -L$(DEPSDIR)/lib
REQ = $(LIBNETFILTER_QUEUE) $(LIBMNL) $(LIBCRYPTO) REQ = $(LIBNETFILTER_QUEUE) $(LIBMNL) $(LIBCRYPTO)
else
override CFLAGS += -Wall -Wpedantic -Wno-unused-variable -std=gnu11
endif endif
override CFLAGS += -DPKG_VERSION=\"$(PKG_FULLVERSION)\" -Wall -Wpedantic -Wno-unused-variable -std=gnu99
LIBNFNETLINK_CFLAGS := -I$(DEPSDIR)/include LIBNFNETLINK_CFLAGS := -I$(DEPSDIR)/include
LIBNFNETLINK_LIBS := -L$(DEPSDIR)/lib LIBNFNETLINK_LIBS := -L$(DEPSDIR)/lib
LIBMNL_CFLAGS := -I$(DEPSDIR)/include LIBMNL_CFLAGS := -I$(DEPSDIR)/include

28
utils.c
View File

@@ -81,20 +81,20 @@ int ip4_payload_split(uint8_t *pkt, uint32_t buflen,
struct iphdr **iph, uint32_t *iph_len, struct iphdr **iph, uint32_t *iph_len,
uint8_t **payload, uint32_t *plen) { uint8_t **payload, uint32_t *plen) {
if (pkt == NULL || buflen < sizeof(struct iphdr)) { if (pkt == NULL || buflen < sizeof(struct iphdr)) {
lgerror("ip4_payload_split: pkt|buflen", -EINVAL); lgerror(-EINVAL, "ip4_payload_split: pkt|buflen");
return -EINVAL; return -EINVAL;
} }
struct iphdr *hdr = (struct iphdr *)pkt; struct iphdr *hdr = (struct iphdr *)pkt;
if (netproto_version(pkt, buflen) != IP4VERSION) { if (netproto_version(pkt, buflen) != IP4VERSION) {
lgerror("ip4_payload_split: ipversion", -EINVAL); lgerror(-EINVAL, "ip4_payload_split: ipversion");
return -EINVAL; return -EINVAL;
} }
uint32_t hdr_len = hdr->ihl * 4; uint32_t hdr_len = hdr->ihl * 4;
uint32_t pktlen = ntohs(hdr->tot_len); uint32_t pktlen = ntohs(hdr->tot_len);
if (buflen < pktlen || hdr_len > pktlen) { if (buflen < pktlen || hdr_len > pktlen) {
lgerror("ip4_payload_split: buflen cmp pktlen", -EINVAL); lgerror(-EINVAL, "ip4_payload_split: buflen cmp pktlen");
return -EINVAL; return -EINVAL;
} }
@@ -156,20 +156,20 @@ int ip6_payload_split(uint8_t *pkt, uint32_t buflen,
struct ip6_hdr **iph, uint32_t *iph_len, struct ip6_hdr **iph, uint32_t *iph_len,
uint8_t **payload, uint32_t *plen) { uint8_t **payload, uint32_t *plen) {
if (pkt == NULL || buflen < sizeof(struct ip6_hdr)) { if (pkt == NULL || buflen < sizeof(struct ip6_hdr)) {
lgerror("ip6_payload_split: pkt|buflen", -EINVAL); lgerror(-EINVAL, "ip6_payload_split: pkt|buflen");
return -EINVAL; return -EINVAL;
} }
struct ip6_hdr *hdr = (struct ip6_hdr *)pkt; struct ip6_hdr *hdr = (struct ip6_hdr *)pkt;
if (netproto_version(pkt, buflen) != 6) { if (netproto_version(pkt, buflen) != 6) {
lgerror("ip6_payload_split: ip6version", -EINVAL); lgerror(-EINVAL, "ip6_payload_split: ip6version");
return -EINVAL; return -EINVAL;
} }
uint32_t hdr_len = sizeof(struct ip6_hdr); uint32_t hdr_len = sizeof(struct ip6_hdr);
uint32_t pktlen = ntohs(hdr->ip6_plen); uint32_t pktlen = ntohs(hdr->ip6_plen);
if (buflen < pktlen) { if (buflen < pktlen) {
lgerror("ip6_payload_split: buflen cmp pktlen: %d %d", -EINVAL, buflen, pktlen); lgerror(-EINVAL, "ip6_payload_split: buflen cmp pktlen: %d %d", buflen, pktlen);
return -EINVAL; return -EINVAL;
} }
@@ -237,7 +237,7 @@ int tcp_payload_split(uint8_t *pkt, uint32_t buflen,
} else if (netvers == IP6VERSION) { } else if (netvers == IP6VERSION) {
return tcp6_payload_split(pkt, buflen, (struct ip6_hdr **)iph, iph_len, tcph, tcph_len, payload, plen); return tcp6_payload_split(pkt, buflen, (struct ip6_hdr **)iph, iph_len, tcph, tcph_len, payload, plen);
} else { } else {
lgerror("Internet Protocol version is unsupported", -EINVAL); lgerror(-EINVAL, "Internet Protocol version is unsupported");
return -EINVAL; return -EINVAL;
} }
} }
@@ -329,7 +329,7 @@ int udp_payload_split(uint8_t *pkt, uint32_t buflen,
} else if (netvers == IP6VERSION) { } else if (netvers == IP6VERSION) {
return udp6_payload_split(pkt, buflen, (struct ip6_hdr **)iph, iph_len, udph, payload, plen); return udp6_payload_split(pkt, buflen, (struct ip6_hdr **)iph, iph_len, udph, payload, plen);
} else { } else {
lgerror("Internet Protocol version is unsupported", -EINVAL); lgerror(-EINVAL, "Internet Protocol version is unsupported");
return -EINVAL; return -EINVAL;
} }
} }
@@ -351,7 +351,7 @@ int ip4_frag(const uint8_t *pkt, uint32_t buflen, uint32_t payload_offset,
if ((ret = ip4_payload_split( if ((ret = ip4_payload_split(
(uint8_t *)pkt, buflen, (uint8_t *)pkt, buflen,
&hdr, &hdr_len, (uint8_t **)&payload, &plen)) < 0) { &hdr, &hdr_len, (uint8_t **)&payload, &plen)) < 0) {
lgerror("ipv4_frag: TCP Header extract error", ret); lgerror(ret, "ipv4_frag: TCP Header extract error");
return -EINVAL; return -EINVAL;
} }
@@ -360,7 +360,7 @@ int ip4_frag(const uint8_t *pkt, uint32_t buflen, uint32_t payload_offset,
} }
if (payload_offset & ((1 << 3) - 1)) { if (payload_offset & ((1 << 3) - 1)) {
lgerror("ipv4_frag: Payload offset MUST be a multiply of 8!", -EINVAL); lgerror(-EINVAL, "ipv4_frag: Payload offset MUST be a multiply of 8!");
return -EINVAL; return -EINVAL;
} }
@@ -433,7 +433,7 @@ int tcp_frag(const uint8_t *pkt, uint32_t buflen, uint32_t payload_offset,
&hdr, &hdr_len, &hdr, &hdr_len,
&tcph, &tcph_len, &tcph, &tcph_len,
(uint8_t **)&payload, &plen)) < 0) { (uint8_t **)&payload, &plen)) < 0) {
lgerror("tcp_frag: tcp_payload_split", ret); lgerror(ret, "tcp_frag: tcp_payload_split");
return -EINVAL; return -EINVAL;
} }
@@ -448,7 +448,7 @@ int tcp_frag(const uint8_t *pkt, uint32_t buflen, uint32_t payload_offset,
ntohs(iphdr->frag_off) & IP_OFFMASK) { ntohs(iphdr->frag_off) & IP_OFFMASK) {
lgdebugmsg("tcp_frag: ip4: frag value: %d", lgdebugmsg("tcp_frag: ip4: frag value: %d",
ntohs(iphdr->frag_off)); ntohs(iphdr->frag_off));
lgerror("tcp_frag: ip4: ip fragmentation is set", -EINVAL); lgerror(-EINVAL, "tcp_frag: ip4: ip fragmentation is set");
return -EINVAL; return -EINVAL;
} }
} }
@@ -590,7 +590,7 @@ int fail_packet(struct failing_strategy strategy, uint8_t *payload, uint32_t *pl
} else if (ipxv == IP6VERSION) { } else if (ipxv == IP6VERSION) {
((struct ip6_hdr *)iph)->ip6_hops = strategy.faking_ttl; ((struct ip6_hdr *)iph)->ip6_hops = strategy.faking_ttl;
} else { } else {
lgerror("fail_packet: IP version is unsupported", -EINVAL); lgerror(-EINVAL, "fail_packet: IP version is unsupported");
return -EINVAL; return -EINVAL;
} }
} else if (strategy.strategy == FAKE_STRAT_TCP_MD5SUM) { } else if (strategy.strategy == FAKE_STRAT_TCP_MD5SUM) {
@@ -612,7 +612,7 @@ int fail_packet(struct failing_strategy strategy, uint8_t *payload, uint32_t *pl
} else if (ipxv == IP6VERSION) { } else if (ipxv == IP6VERSION) {
((struct ip6_hdr *)iph)->ip6_plen = htons(ntohs(((struct ip6_hdr *)iph)->ip6_plen) + delta); ((struct ip6_hdr *)iph)->ip6_plen = htons(ntohs(((struct ip6_hdr *)iph)->ip6_plen) + delta);
} else { } else {
lgerror("fail_packet: IP version is unsupported", -EINVAL); lgerror(-EINVAL, "fail_packet: IP version is unsupported");
return -EINVAL; return -EINVAL;
} }
optp_len += delta; optp_len += delta;

View File

@@ -45,12 +45,12 @@ static int open_socket(struct mnl_socket **_nl) {
nl = mnl_socket_open(NETLINK_NETFILTER); nl = mnl_socket_open(NETLINK_NETFILTER);
if (nl == NULL) { if (nl == NULL) {
perror("mnl_socket_open"); lgerror(errno, "mnl_socket_open");
return -1; return -1;
} }
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
perror("mnl_socket_bind"); lgerror(errno, "mnl_socket_bind");
mnl_socket_close(nl); mnl_socket_close(nl);
return -1; return -1;
} }
@@ -65,7 +65,7 @@ static int close_socket(struct mnl_socket **_nl) {
struct mnl_socket *nl = *_nl; struct mnl_socket *nl = *_nl;
if (nl == NULL) return 1; if (nl == NULL) return 1;
if (mnl_socket_close(nl) < 0) { if (mnl_socket_close(nl) < 0) {
perror("mnl_socket_close"); lgerror(errno, "mnl_socket_close");
return -1; return -1;
} }
@@ -77,26 +77,26 @@ static int close_socket(struct mnl_socket **_nl) {
static int open_raw_socket(void) { static int open_raw_socket(void) {
if (rawsocket != -2) { if (rawsocket != -2) {
errno = EALREADY; errno = EALREADY;
perror("Raw socket is already opened"); lgerror(errno, "Raw socket is already opened");
return -1; return -1;
} }
rawsocket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); rawsocket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (rawsocket == -1) { if (rawsocket == -1) {
perror("Unable to create raw socket"); lgerror(errno, "Unable to create raw socket");
return -1; return -1;
} }
int mark = config.mark; int mark = config.mark;
if (setsockopt(rawsocket, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0) if (setsockopt(rawsocket, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0)
{ {
fprintf(stderr, "setsockopt(SO_MARK, %d) failed\n", mark); lgerror(errno, "setsockopt(SO_MARK, %d) failed\n", mark);
return -1; return -1;
} }
int mst = pthread_mutex_init(&rawsocket_lock, NULL); int mst = pthread_mutex_init(&rawsocket_lock, NULL);
if (mst) { if (mst) {
fprintf(stderr, "Mutex err: %d\n", mst); lgerror(errno, "Mutex err: %d\n", mst);
close(rawsocket); close(rawsocket);
errno = mst; errno = mst;
@@ -110,12 +110,12 @@ static int open_raw_socket(void) {
static int close_raw_socket(void) { static int close_raw_socket(void) {
if (rawsocket < 0) { if (rawsocket < 0) {
errno = EALREADY; errno = EALREADY;
perror("Raw socket is not set"); lgerror(errno, "Raw socket is not set");
return -1; return -1;
} }
if (close(rawsocket)) { if (close(rawsocket)) {
perror("Unable to close raw socket"); lgerror(errno, "Unable to close raw socket");
pthread_mutex_destroy(&rawsocket_lock); pthread_mutex_destroy(&rawsocket_lock);
return -1; return -1;
} }
@@ -129,26 +129,26 @@ static int close_raw_socket(void) {
static int open_raw6_socket(void) { static int open_raw6_socket(void) {
if (raw6socket != -2) { if (raw6socket != -2) {
errno = EALREADY; errno = EALREADY;
perror("Raw socket is already opened"); lgerror(errno, "Raw socket is already opened");
return -1; return -1;
} }
raw6socket = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW); raw6socket = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
if (rawsocket == -1) { if (rawsocket == -1) {
perror("Unable to create raw socket"); lgerror(errno, "Unable to create raw socket");
return -1; return -1;
} }
int mark = config.mark; int mark = config.mark;
if (setsockopt(raw6socket, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0) if (setsockopt(raw6socket, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0)
{ {
fprintf(stderr, "setsockopt(SO_MARK, %d) failed\n", mark); lgerror(errno, "setsockopt(SO_MARK, %d) failed\n", mark);
return -1; return -1;
} }
int mst = pthread_mutex_init(&raw6socket_lock, NULL); int mst = pthread_mutex_init(&raw6socket_lock, NULL);
if (mst) { if (mst) {
fprintf(stderr, "Mutex err: %d\n", mst); lgerror(mst, "Mutex err: %d\n", mst);
close(raw6socket); close(raw6socket);
errno = mst; errno = mst;
@@ -162,12 +162,12 @@ static int open_raw6_socket(void) {
static int close_raw6_socket(void) { static int close_raw6_socket(void) {
if (raw6socket < 0) { if (raw6socket < 0) {
errno = EALREADY; errno = EALREADY;
perror("Raw socket is not set"); lgerror(errno, "Raw socket is not set");
return -1; return -1;
} }
if (close(raw6socket)) { if (close(raw6socket)) {
perror("Unable to close raw socket"); lgerror(errno, "Unable to close raw socket");
pthread_mutex_destroy(&rawsocket_lock); pthread_mutex_destroy(&rawsocket_lock);
return -1; return -1;
} }
@@ -203,7 +203,7 @@ static int send_raw_ipv4(const uint8_t *pkt, uint32_t pktlen) {
pthread_mutex_lock(&rawsocket_lock); pthread_mutex_lock(&rawsocket_lock);
int sent = sendto(rawsocket, int sent = sendto(rawsocket,
pkt, pktlen, 0, pkt, pktlen, MSG_DONTWAIT,
(struct sockaddr *)&daddr, sizeof(daddr)); (struct sockaddr *)&daddr, sizeof(daddr));
if (config.threads != 1) if (config.threads != 1)
@@ -238,7 +238,7 @@ static int send_raw_ipv6(const uint8_t *pkt, uint32_t pktlen) {
pthread_mutex_lock(&rawsocket_lock); pthread_mutex_lock(&rawsocket_lock);
int sent = sendto(raw6socket, int sent = sendto(raw6socket,
pkt, pktlen, 0, pkt, pktlen, MSG_DONTWAIT,
(struct sockaddr *)&daddr, sizeof(daddr)); (struct sockaddr *)&daddr, sizeof(daddr));
lgtrace_addp("rawsocket sent %d", sent); lgtrace_addp("rawsocket sent %d", sent);
@@ -256,19 +256,29 @@ static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
int ret; int ret;
if (pktlen > AVAILABLE_MTU) { if (pktlen > AVAILABLE_MTU) {
if (config.verbose) lgtrace("Split packet!\n");
printf("Split packet!\n");
NETBUF_ALLOC(buff1, MNL_SOCKET_BUFFER_SIZE);
if (!NETBUF_CHECK(buff1)) {
lgerror(-ENOMEM, "Allocation error");
return -ENOMEM;
}
NETBUF_ALLOC(buff2, MNL_SOCKET_BUFFER_SIZE);
if (!NETBUF_CHECK(buff2)) {
lgerror(-ENOMEM, "Allocation error");
NETBUF_FREE(buff1);
return -ENOMEM;
}
uint8_t buff1[MNL_SOCKET_BUFFER_SIZE];
uint32_t buff1_size = MNL_SOCKET_BUFFER_SIZE; uint32_t buff1_size = MNL_SOCKET_BUFFER_SIZE;
uint8_t buff2[MNL_SOCKET_BUFFER_SIZE];
uint32_t buff2_size = MNL_SOCKET_BUFFER_SIZE; uint32_t buff2_size = MNL_SOCKET_BUFFER_SIZE;
if ((ret = tcp_frag(pkt, pktlen, AVAILABLE_MTU-128, if ((ret = tcp_frag(pkt, pktlen, AVAILABLE_MTU-128,
buff1, &buff1_size, buff2, &buff2_size)) < 0) { buff1, &buff1_size, buff2, &buff2_size)) < 0) {
errno = -ret; errno = -ret;
return ret; goto free_buffs;
} }
int sent = 0; int sent = 0;
@@ -276,16 +286,23 @@ static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
if (status >= 0) sent += status; if (status >= 0) sent += status;
else { else {
return status; ret = status;
goto free_buffs;
} }
status = send_raw_socket(buff2, buff2_size); status = send_raw_socket(buff2, buff2_size);
if (status >= 0) sent += status; if (status >= 0) sent += status;
else { else {
return status; ret = status;
goto free_buffs;
} }
return sent; ret = sent;
free_buffs:
NETBUF_FREE(buff1)
NETBUF_FREE(buff2)
return ret;
} }
int ipvx = netproto_version(pkt, pktlen); int ipvx = netproto_version(pkt, pktlen);
@@ -295,7 +312,7 @@ static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
} else if (ipvx == IP6VERSION) { } else if (ipvx == IP6VERSION) {
ret = send_raw_ipv6(pkt, pktlen); ret = send_raw_ipv6(pkt, pktlen);
} else { } else {
printf("proto version %d is unsupported\n", ipvx); lginfo("proto version %d is unsupported\n", ipvx);
return -EINVAL; return -EINVAL;
} }
@@ -328,7 +345,7 @@ static int fallback_accept_packet(uint32_t id, struct queue_data qdata) {
nfq_nlmsg_verdict_put(verdnlh, id, NF_ACCEPT); nfq_nlmsg_verdict_put(verdnlh, id, NF_ACCEPT);
if (mnl_socket_sendto(*qdata._nl, verdnlh, verdnlh->nlmsg_len) < 0) { if (mnl_socket_sendto(*qdata._nl, verdnlh, verdnlh->nlmsg_len) < 0) {
perror("mnl_socket_send"); lgerror(errno, "mnl_socket_send");
return MNL_CB_ERROR; return MNL_CB_ERROR;
} }
@@ -353,7 +370,7 @@ void *delay_packet_send_fn(void *data) {
int ret = send_raw_socket(pkt, pktlen); int ret = send_raw_socket(pkt, pktlen);
if (ret < 0) { if (ret < 0) {
errno = -ret; errno = -ret;
perror("send delayed raw packet"); lgerror(errno, "send delayed raw packet");
} }
free(pkt); free(pkt);
@@ -385,13 +402,13 @@ static int queue_cb(const struct nlmsghdr *nlh, void *data) {
struct packet_data packet = {0}; struct packet_data packet = {0};
if (nfq_nlmsg_parse(nlh, attr) < 0) { if (nfq_nlmsg_parse(nlh, attr) < 0) {
perror("Attr parse"); lgerror(errno, "Attr parse");
return MNL_CB_ERROR; return MNL_CB_ERROR;
} }
if (attr[NFQA_PACKET_HDR] == NULL) { if (attr[NFQA_PACKET_HDR] == NULL) {
errno = ENODATA; errno = ENODATA;
perror("Metaheader not set"); lgerror(errno, "Metaheader not set");
return MNL_CB_ERROR; return MNL_CB_ERROR;
} }
@@ -404,7 +421,7 @@ static int queue_cb(const struct nlmsghdr *nlh, void *data) {
packet.payload = mnl_attr_get_payload(attr[NFQA_PAYLOAD]); packet.payload = mnl_attr_get_payload(attr[NFQA_PAYLOAD]);
if (attr[NFQA_CAP_LEN] != NULL && ntohl(mnl_attr_get_u32(attr[NFQA_CAP_LEN])) != packet.payload_len) { if (attr[NFQA_CAP_LEN] != NULL && ntohl(mnl_attr_get_u32(attr[NFQA_CAP_LEN])) != packet.payload_len) {
fprintf(stderr, "The packet was truncated! Skip!\n"); lgerr("The packet was truncated! Skip!\n");
return fallback_accept_packet(packet.id, *qdata); return fallback_accept_packet(packet.id, *qdata);
} }
@@ -432,7 +449,7 @@ static int queue_cb(const struct nlmsghdr *nlh, void *data) {
} }
if (mnl_socket_sendto(*qdata->_nl, verdnlh, verdnlh->nlmsg_len) < 0) { if (mnl_socket_sendto(*qdata->_nl, verdnlh, verdnlh->nlmsg_len) < 0) {
perror("mnl_socket_send"); lgerror(errno, "mnl_socket_send");
return MNL_CB_ERROR; return MNL_CB_ERROR;
} }
@@ -445,20 +462,64 @@ int init_queue(int queue_num) {
struct mnl_socket *nl; struct mnl_socket *nl;
if (open_socket(&nl)) { if (open_socket(&nl)) {
perror("Unable to open socket"); lgerror(errno, "Unable to open socket");
return -1; return -1;
} }
uint32_t portid = mnl_socket_get_portid(nl); uint32_t portid = mnl_socket_get_portid(nl);
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
char buf[BUF_SIZE]; NETBUF_ALLOC(bbuf, BUF_SIZE);
if (!NETBUF_CHECK(bbuf)) {
lgerror(-ENOMEM, "Allocation error");
goto die_alloc;
}
char *buf = (char *)bbuf;
/* Support for kernels versions < 3.8 */
// Obsolete and ignored in kernel version 3.8
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0360ae412d09bc6f4864c801effcb20bfd84520e
nlh = nfq_nlmsg_put(buf, NFQNL_MSG_CONFIG, queue_num);
nfq_nlmsg_cfg_put_cmd(nlh, PF_INET, NFQNL_CFG_CMD_PF_UNBIND);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
lgerror(errno, "mnl_socket_send");
goto die;
}
nlh = nfq_nlmsg_put(buf, NFQNL_MSG_CONFIG, queue_num);
nfq_nlmsg_cfg_put_cmd(nlh, PF_INET, NFQNL_CFG_CMD_PF_BIND);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
lgerror(errno, "mnl_socket_send");
goto die;
}
if (config.use_ipv6) {
nlh = nfq_nlmsg_put(buf, NFQNL_MSG_CONFIG, queue_num);
nfq_nlmsg_cfg_put_cmd(nlh, PF_INET6, NFQNL_CFG_CMD_PF_UNBIND);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
lgerror(errno, "mnl_socket_send");
goto die;
}
nlh = nfq_nlmsg_put(buf, NFQNL_MSG_CONFIG, queue_num);
nfq_nlmsg_cfg_put_cmd(nlh, PF_INET6, NFQNL_CFG_CMD_PF_BIND);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
lgerror(errno, "mnl_socket_send");
goto die;
}
}
/* End of support for kernel versions < 3.8 */
nlh = nfq_nlmsg_put(buf, NFQNL_MSG_CONFIG, queue_num); nlh = nfq_nlmsg_put(buf, NFQNL_MSG_CONFIG, queue_num);
nfq_nlmsg_cfg_put_cmd(nlh, AF_INET, NFQNL_CFG_CMD_BIND); nfq_nlmsg_cfg_put_cmd(nlh, AF_INET, NFQNL_CFG_CMD_BIND);
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_send"); lgerror(errno, "mnl_socket_send");
goto die; goto die;
} }
@@ -471,7 +532,7 @@ int init_queue(int queue_num) {
} }
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
perror("mnl_socket_send"); lgerror(errno, "mnl_socket_send");
goto die; goto die;
} }
@@ -488,32 +549,35 @@ int init_queue(int queue_num) {
.queue_num = queue_num .queue_num = queue_num
}; };
printf("Queue %d started\n", qdata.queue_num); lginfo("Queue %d started\n", qdata.queue_num);
while (1) { while (1) {
ret = mnl_socket_recvfrom(nl, buf, BUF_SIZE); ret = mnl_socket_recvfrom(nl, buf, BUF_SIZE);
if (ret == -1) { if (ret == -1) {
perror("mnl_socket_recvfrom"); lgerror(errno, "mnl_socket_recvfrom");
goto die; goto die;
} }
ret = mnl_cb_run(buf, ret, 0, portid, queue_cb, &qdata); ret = mnl_cb_run(buf, ret, 0, portid, queue_cb, &qdata);
if (ret < 0) { if (ret < 0) {
lgerror("mnl_cb_run", -EPERM); lgerror(-EPERM, "mnl_cb_run");
if (errno == EPERM) { if (errno == EPERM) {
printf("Probably another instance of youtubeUnblock with the same queue number is running\n"); lgerror(errno, "Probably another instance of youtubeUnblock with the same queue number is running\n");
} else { } else {
printf("Make sure the nfnetlink_queue kernel module is loaded\n"); lgerror(errno, "Make sure the nfnetlink_queue kernel module is loaded\n");
} }
goto die; goto die;
} }
} }
NETBUF_FREE(bbuf)
close_socket(&nl); close_socket(&nl);
return 0; return 0;
die: die:
NETBUF_FREE(bbuf)
die_alloc:
close_socket(&nl); close_socket(&nl);
return -1; return -1;
} }
@@ -537,7 +601,7 @@ void *init_queue_wrapper(void *qdconf) {
thres->status = init_queue(qconf->queue_num); thres->status = init_queue(qconf->queue_num);
fprintf(stderr, "Thread %d exited with status %d\n", qconf->i, thres->status); lgerror(thres->status, "Thread %d exited with status %d\n", qconf->i, thres->status);
return thres; return thres;
} }
@@ -551,7 +615,7 @@ int main(int argc, char *argv[]) {
int ret; int ret;
if ((ret = parse_args(argc, argv)) != 0) { if ((ret = parse_args(argc, argv)) != 0) {
if (ret < 0) { if (ret < 0) {
perror("Unable to parse args"); lgerror(errno, "Unable to parse args");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
@@ -560,19 +624,24 @@ int main(int argc, char *argv[]) {
print_version(); print_version();
print_welcome(); print_welcome();
if (open_raw_socket() < 0) { if (open_raw_socket() < 0) {
perror("Unable to open raw socket"); lgerror(errno, "Unable to open raw socket");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (config.use_ipv6) { if (config.use_ipv6) {
if (open_raw6_socket() < 0) { if (open_raw6_socket() < 0) {
perror("Unable to open raw socket for ipv6"); lgerror(errno, "Unable to open raw socket for ipv6");
close_raw_socket(); close_raw_socket();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
if (config.daemonize) {
daemon(0, config.noclose);
}
struct queue_res *qres = &defqres; struct queue_res *qres = &defqres;
if (config.threads == 1) { if (config.threads == 1) {
@@ -583,7 +652,7 @@ int main(int argc, char *argv[]) {
qres = init_queue_wrapper(&tconf); qres = init_queue_wrapper(&tconf);
} else { } else {
printf("%d threads wil be used\n", config.threads); lginfo("%d threads wil be used\n", config.threads);
struct queue_conf thread_confs[MAX_THREADS]; struct queue_conf thread_confs[MAX_THREADS];
pthread_t threads[MAX_THREADS]; pthread_t threads[MAX_THREADS];