Compare commits

..

21 Commits

Author SHA1 Message Date
世界
7ec275b54b documentation: Bump version 2023-12-12 14:17:27 +08:00
世界
89eb866a70 Refactor inbound/outbound options struct 2023-12-12 14:17:27 +08:00
世界
5a235dff20 Improve configuration merge 2023-12-12 14:17:27 +08:00
世界
3afc8d815c Update uTLS to 1.5.4 2023-12-12 14:17:27 +08:00
世界
2d45adf2bb Update tfo-go 2023-12-12 14:17:27 +08:00
世界
7eb0ded48d Update gomobile and add tag 2023-12-12 14:17:27 +08:00
世界
d6d4c9826c Update cloudflare-tls to go1.21.5 2023-12-12 14:17:27 +08:00
世界
ac2c01ad72 Improve read wait interface &
Refactor Authenticator interface to struct &
Update smux &
Update gVisor to 20231204.0 &
Update wireguard-go &
Add GSO support for TUN/WireGuard
2023-12-12 14:17:27 +08:00
世界
94d18e9649 Make type check strict 2023-12-12 14:17:27 +08:00
世界
036edee6d9 Remove comparable limit for Listable 2023-12-12 14:17:27 +08:00
世界
4f668b4d7b Avoid opening log output before start &
Replace tracing logs with task monitor
2023-12-12 14:17:27 +08:00
世界
c60465a01f Update documentation 2023-12-12 14:08:26 +08:00
世界
cf6d8318e2 Add idle_timeout for URLTest outbound 2023-12-12 14:08:26 +08:00
世界
b8fc1f7e58 Skip internal fake-ip queries 2023-12-12 14:08:25 +08:00
世界
7888a15fa5 Migrate contentjson and badjson to library &
Add omitempty in format
2023-12-12 14:08:25 +08:00
世界
894f39ec0f Update documentation 2023-12-12 14:08:25 +08:00
世界
5d3ffb62dc Independent source_ip_is_private and ip_is_private rules 2023-12-12 14:08:25 +08:00
世界
ce316c182d Add rule-set 2023-12-12 14:08:16 +08:00
世界
f594f186fb Update buffer usage 2023-12-12 14:08:16 +08:00
世界
6259717410 Allow nested logical rules 2023-12-12 14:08:14 +08:00
世界
50689ca969 Migrate to independent cache file 2023-12-12 14:08:12 +08:00
253 changed files with 2571 additions and 4735 deletions

1
.github/FUNDING.yml vendored
View File

@@ -1 +0,0 @@
github: nekohasekai

View File

@@ -61,28 +61,7 @@ body:
attributes: attributes:
label: Logs label: Logs
description: |- description: |-
In addition, if you encounter a crash with the graphical client, please also provide crash logs. If you encounter a crash with the graphical client, please provide crash logs.
For Apple platform clients, please check `Settings - View Service Log` for crash logs. For Apple platform clients, please check `Settings - View Service Log` for crash logs.
For the Android client, please check the `/sdcard/Android/data/io.nekohasekai.sfa/files/stderr.log` file for crash logs. For the Android client, please check the `/sdcard/Android/data/io.nekohasekai.sfa/files/stderr.log` file for crash logs.
render: shell render: shell
- type: checkboxes
id: supporter
attributes:
label: Supporter
options:
- label: I am a [sponsor](https://github.com/sponsors/nekohasekai/)
- type: checkboxes
attributes:
label: Integrity requirements
description: |-
Please check all of the following options to prove that you have read and understood the requirements, otherwise this issue will be closed.
Sing-box is not a project aimed to please users who can't make any meaningful contributions and gain unethical influence. If you deceive here to deliberately waste the time of the developers, you will be permanently blocked.
options:
- label: I confirm that I have read the documentation, understand the meaning of all the configuration items I wrote, and did not pile up seemingly useful options or default values.
required: true
- label: I confirm that I have provided the server and client configuration files and process that can be reproduced locally, instead of a complicated client configuration file that has been stripped of sensitive data.
required: true
- label: I confirm that I have provided the simplest configuration that can be used to reproduce the error I reported, instead of depending on remote servers, TUN, graphical interface clients, or other closed-source software.
required: true
- label: I confirm that I have provided the complete configuration files and logs, rather than just providing parts I think are useful out of confidence in my own intelligence.
required: true

View File

@@ -61,28 +61,21 @@ body:
attributes: attributes:
label: 日志 label: 日志
description: |- description: |-
此外,如果您遭遇图形界面应用程序崩溃,请附加提供崩溃日志。 如果您遭遇图形界面应用程序崩溃,请提供崩溃日志。
对于 Apple 平台图形客户端程序,请检查 `Settings - View Service Log` 以导出崩溃日志。 对于 Apple 平台图形客户端程序,请检查 `Settings - View Service Log` 以导出崩溃日志。
对于 Android 图形客户端程序,请检查 `/sdcard/Android/data/io.nekohasekai.sfa/files/stderr.log` 文件以导出崩溃日志。 对于 Android 图形客户端程序,请检查 `/sdcard/Android/data/io.nekohasekai.sfa/files/stderr.log` 文件以导出崩溃日志。
render: shell render: shell
- type: checkboxes
id: supporter
attributes:
label: 支持我们
options:
- label: 我已经 [赞助](https://github.com/sponsors/nekohasekai/)
- type: checkboxes - type: checkboxes
attributes: attributes:
label: 完整性要求 label: 完整性要求
description: |- description: 我保证我提供了完整的可以在本地重现该问题的服务器、客户端配置文件与流程,而不是一个脱敏的复杂客户端配置文件,否则该 issue 将被关闭。
请勾选以下所有选项以证明您已经阅读并理解了以下要求,否则该 issue 将被关闭。
sing-box 不是讨好无法作出任何意义上的贡献的最终用户并获取非道德影响力的项目,如果您在此处欺骗以故意浪费开发者的时间,您将被永久封锁。
options: options:
- label: 我保证阅读了文档,了解所有我编写的配置文件项的含义,而不是大量堆砌看似有用的选项或默认值。 - label: 我保证
required: true
- label: 我保证提供了可以在本地重现该问题的服务器、客户端配置文件与流程,而不是一个脱敏的复杂客户端配置文件。
required: true
- label: 我保证提供了可用于重现我报告的错误的最简配置而不是依赖远程服务器、TUN、图形界面客户端或者其他闭源软件。
required: true
- label: 我保证提供了完整的配置文件与日志,而不是出于对自身智力的自信而仅提供了部分认为有用的部分。
required: true required: true
- type: checkboxes
attributes:
label: 负责性要求
description: 我保证我阅读了文档,了解所有我编写的配置文件项的含义,而不是大量堆砌看似有用的选项或默认值,否则该 issue 将被关闭。
options:
- label: 我保证
required: true

View File

@@ -1,14 +0,0 @@
#!/usr/bin/env bash
PROJECTS=$(dirname "$0")/../..
function updateClient() {
pushd clients/$1
git fetch
git reset FETCH_HEAD --hard
popd
git add clients/$1
}
updateClient "apple"
updateClient "android"

View File

@@ -22,13 +22,25 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Get latest go version
id: version
run: |
echo go_version=$(curl -s https://raw.githubusercontent.com/actions/go-versions/main/versions-manifest.json | grep -oE '"version": "[0-9]{1}.[0-9]{1,}(.[0-9]{1,})?"' | head -1 | cut -d':' -f2 | sed 's/ //g; s/"//g') >> $GITHUB_OUTPUT
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v5 uses: actions/setup-go@v4
with: with:
go-version: ^1.22 go-version: ${{ steps.version.outputs.go_version }}
- name: Add cache to Go proxy
run: |
version=`git rev-parse HEAD`
mkdir build
pushd build
go mod init build
go get -v github.com/sagernet/sing-box@$version
popd
continue-on-error: true continue-on-error: true
- name: Run Test - name: Run Test
run: | run: |
@@ -38,15 +50,15 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v5 uses: actions/setup-go@v4
with: with:
go-version: ~1.18 go-version: 1.18.10
- name: Cache go module - name: Cache go module
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: | path: |
~/go/pkg/mod ~/go/pkg/mod
@@ -58,39 +70,19 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v5 uses: actions/setup-go@v4
with: with:
go-version: ~1.20 go-version: 1.20.7
- name: Cache go module - name: Cache go module
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: | path: |
~/go/pkg/mod ~/go/pkg/mod
key: go120-${{ hashFiles('**/go.sum') }} key: go118-${{ hashFiles('**/go.sum') }}
- name: Run Test
run: make ci_build_go120
build_go121:
name: Debug build (Go 1.21)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.21
- name: Cache go module
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
key: go121-${{ hashFiles('**/go.sum') }}
- name: Run Test - name: Run Test
run: make ci_build run: make ci_build
cross: cross:
@@ -196,7 +188,8 @@ jobs:
- name: freebsd-arm64 - name: freebsd-arm64
goos: freebsd goos: freebsd
goarch: arm64 goarch: arm64
fail-fast: true
fail-fast: false
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: env:
GOOS: ${{ matrix.goos }} GOOS: ${{ matrix.goos }}
@@ -208,13 +201,22 @@ jobs:
TAGS: with_clash_api,with_quic TAGS: with_clash_api,with_quic
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Get latest go version
id: version
run: |
echo go_version=$(curl -s https://raw.githubusercontent.com/actions/go-versions/main/versions-manifest.json | grep -oE '"version": "[0-9]{1}.[0-9]{1,}(.[0-9]{1,})?"' | head -1 | cut -d':' -f2 | sed 's/ //g; s/"//g') >> $GITHUB_OUTPUT
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v5 uses: actions/setup-go@v4
with: with:
go-version: ^1.21 go-version: ${{ steps.version.outputs.go_version }}
- name: Build - name: Build
id: build id: build
run: make run: make
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: sing-box-${{ matrix.name }}
path: sing-box*

View File

@@ -1,9 +1,5 @@
name: Build Docker Images name: Build Docker Images
on: on:
release:
types:
- released
workflow_dispatch: workflow_dispatch:
inputs: inputs:
tag: tag:
@@ -12,27 +8,8 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Get commit to build
id: ref
run: |-
if [[ -z "${{ github.event.inputs.tag }}" ]]; then
ref="${{ github.ref_name }}"
else
ref="${{ github.event.inputs.tag }}"
fi
echo "ref=$ref"
echo "ref=$ref" >> $GITHUB_OUTPUT
if [[ $ref == *"-"* ]]; then
latest=latest-beta
else
latest=latest
fi
echo "latest=$latest"
echo "latest=$latest" >> $GITHUB_OUTPUT
- name: Checkout - name: Checkout
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
with:
ref: ${{ steps.ref.outputs.ref }}
- name: Setup Docker Buildx - name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Setup QEMU for Docker Buildx - name: Setup QEMU for Docker Buildx
@@ -48,15 +25,23 @@ jobs:
uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
with: with:
images: ghcr.io/sagernet/sing-box images: ghcr.io/sagernet/sing-box
- name: Get tag to build
id: tag
run: |
echo "latest=ghcr.io/sagernet/sing-box:latest" >> $GITHUB_OUTPUT
if [[ -z "${{ github.event.inputs.tag }}" ]]; then
echo "versioned=ghcr.io/sagernet/sing-box:${{ github.ref_name }}" >> $GITHUB_OUTPUT
else
echo "versioned=ghcr.io/sagernet/sing-box:${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
fi
- name: Build and release Docker images - name: Build and release Docker images
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
with: with:
platforms: linux/386,linux/amd64,linux/arm64,linux/s390x platforms: linux/386,linux/amd64,linux/arm64,linux/s390x
context: .
target: dist target: dist
build-args: | build-args: |
BUILDKIT_CONTEXT_KEEP_GIT_DIR=1 BUILDKIT_CONTEXT_KEEP_GIT_DIR=1
tags: | tags: |
ghcr.io/sagernet/sing-box:${{ steps.ref.outputs.latest }} ${{ steps.tag.outputs.latest }}
ghcr.io/sagernet/sing-box:${{ steps.ref.outputs.ref }} ${{ steps.tag.outputs.versioned }}
push: true push: true

View File

@@ -22,15 +22,19 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Get latest go version
id: version
run: |
echo go_version=$(curl -s https://raw.githubusercontent.com/actions/go-versions/main/versions-manifest.json | grep -oE '"version": "[0-9]{1}.[0-9]{1,}(.[0-9]{1,})?"' | head -1 | cut -d':' -f2 | sed 's/ //g; s/"//g') >> $GITHUB_OUTPUT
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v5 uses: actions/setup-go@v4
with: with:
go-version: ^1.22 go-version: ${{ steps.version.outputs.go_version }}
- name: golangci-lint - name: golangci-lint
uses: golangci/golangci-lint-action@v6 uses: golangci/golangci-lint-action@v3
with: with:
version: latest version: latest
args: --timeout=30m args: --timeout=30m

View File

@@ -1,39 +0,0 @@
name: Release to Linux repository
on:
release:
types:
- published
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ^1.22
- name: Extract signing key
run: |-
mkdir -p $HOME/.gnupg
cat > $HOME/.gnupg/sagernet.key <<EOF
${{ secrets.GPG_KEY }}
echo "HOME=$HOME" >> "$GITHUB_ENV"
EOF
echo "HOME=$HOME" >> "$GITHUB_ENV"
- name: Publish release
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser-pro
version: latest
args: release -f .goreleaser.fury.yaml --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
FURY_TOKEN: ${{ secrets.FURY_TOKEN }}
NFPM_KEY_PATH: ${{ env.HOME }}/.gnupg/sagernet.key
NFPM_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}

View File

@@ -8,7 +8,7 @@ jobs:
stale: stale:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/stale@v9 - uses: actions/stale@v8
with: with:
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days' stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days'
days-before-stale: 60 days-before-stale: 60

6
.gitmodules vendored
View File

@@ -1,6 +0,0 @@
[submodule "clients/apple"]
path = clients/apple
url = https://github.com/SagerNet/sing-box-for-apple.git
[submodule "clients/android"]
path = clients/android
url = https://github.com/SagerNet/sing-box-for-android.git

View File

@@ -1,86 +0,0 @@
project_name: sing-box
builds:
- id: main
main: ./cmd/sing-box
flags:
- -v
- -trimpath
ldflags:
- -X github.com/sagernet/sing-box/constant.Version={{ .Version }} -s -w -buildid=
tags:
- with_gvisor
- with_quic
- with_dhcp
- with_wireguard
- with_ech
- with_utls
- with_reality_server
- with_acme
- with_clash_api
env:
- CGO_ENABLED=0
targets:
- linux_386
- linux_amd64_v1
- linux_arm64
- linux_arm_7
- linux_s390x
- linux_riscv64
mod_timestamp: '{{ .CommitTimestamp }}'
snapshot:
name_template: "{{ .Version }}.{{ .ShortCommit }}"
nfpms:
- &template
id: package
package_name: sing-box
file_name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ with .Arm }}v{{ . }}{{ end }}{{ with .Mips }}_{{ . }}{{ end }}{{ if not (eq .Amd64 "v1") }}{{ .Amd64 }}{{ end }}'
builds:
- main
homepage: https://sing-box.sagernet.org/
maintainer: nekohasekai <contact-git@sekai.icu>
description: The universal proxy platform.
license: GPLv3 or later
formats:
- deb
- rpm
priority: extra
contents:
- src: release/config/config.json
dst: /etc/sing-box/config.json
type: config
- src: release/config/sing-box.service
dst: /usr/lib/systemd/system/sing-box.service
- src: release/config/sing-box@.service
dst: /usr/lib/systemd/system/sing-box@.service
- src: LICENSE
dst: /usr/share/licenses/sing-box/LICENSE
deb:
signature:
key_file: "{{ .Env.NFPM_KEY_PATH }}"
fields:
Bugs: https://github.com/SagerNet/sing-box/issues
rpm:
signature:
key_file: "{{ .Env.NFPM_KEY_PATH }}"
conflicts:
- sing-box-beta
- id: package_beta
<<: *template
package_name: sing-box-beta
file_name_template: '{{ .ProjectName }}-beta_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ with .Arm }}v{{ . }}{{ end }}{{ with .Mips }}_{{ . }}{{ end }}{{ if not (eq .Amd64 "v1") }}{{ .Amd64 }}{{ end }}'
formats:
- deb
- rpm
conflicts:
- sing-box
release:
disable: true
furies:
- account: sagernet
ids:
- package
disable: "{{ not (not .Prerelease) }}"
- account: sagernet
ids:
- package_beta
disable: "{{ not .Prerelease }}"

View File

@@ -1,11 +1,14 @@
project_name: sing-box project_name: sing-box
builds: builds:
- &template - id: main
id: main
main: ./cmd/sing-box main: ./cmd/sing-box
flags: flags:
- -v - -v
- -trimpath - -trimpath
asmflags:
- all=-trimpath={{.Env.GOPATH}}
gcflags:
- all=-trimpath={{.Env.GOPATH}}
ldflags: ldflags:
- -X github.com/sagernet/sing-box/constant.Version={{ .Version }} -s -w -buildid= - -X github.com/sagernet/sing-box/constant.Version={{ .Version }} -s -w -buildid=
tags: tags:
@@ -27,35 +30,65 @@ builds:
- linux_arm64 - linux_arm64
- linux_arm_7 - linux_arm_7
- linux_s390x - linux_s390x
- linux_riscv64
- windows_amd64_v1 - windows_amd64_v1
- windows_amd64_v3 - windows_amd64_v3
- windows_386 - windows_386
- windows_arm64 - windows_arm64
- darwin_amd64_v1 - darwin_amd64_v1
- darwin_amd64_v3
- darwin_arm64 - darwin_arm64
mod_timestamp: '{{ .CommitTimestamp }}' mod_timestamp: '{{ .CommitTimestamp }}'
- id: legacy - id: legacy
<<: *template main: ./cmd/sing-box
flags:
- -v
- -trimpath
asmflags:
- all=-trimpath={{.Env.GOPATH}}
gcflags:
- all=-trimpath={{.Env.GOPATH}}
ldflags:
- -X github.com/sagernet/sing-box/constant.Version={{ .Version }} -s -w -buildid=
tags: tags:
- with_gvisor - with_gvisor
- with_quic - with_quic
- with_dhcp - with_dhcp
- with_wireguard - with_wireguard
- with_ech
- with_utls - with_utls
- with_reality_server - with_reality_server
- with_acme - with_acme
- with_clash_api - with_clash_api
env: env:
- CGO_ENABLED=0 - CGO_ENABLED=0
- GOROOT={{ .Env.GOPATH }}/go1.20.14 - GOROOT=/nix/store/kg6i737jjqs923jcijnm003h68c1dghj-go-1.20.11/share/go
gobinary: "{{ .Env.GOPATH }}/go1.20.14/bin/go" gobinary: /nix/store/kg6i737jjqs923jcijnm003h68c1dghj-go-1.20.11/bin/go
targets: targets:
- windows_amd64_v1 - windows_amd64_v1
- windows_386 - windows_386
- darwin_amd64_v1 - darwin_amd64_v1
mod_timestamp: '{{ .CommitTimestamp }}'
- id: android - id: android
<<: *template main: ./cmd/sing-box
flags:
- -v
- -trimpath
asmflags:
- all=-trimpath={{.Env.GOPATH}}
gcflags:
- all=-trimpath={{.Env.GOPATH}}
ldflags:
- -X github.com/sagernet/sing-box/constant.Version={{ .Version }} -s -w -buildid=
tags:
- with_gvisor
- with_quic
- with_dhcp
- with_wireguard
- with_ech
- with_utls
- with_reality_server
- with_acme
- with_clash_api
env: env:
- CGO_ENABLED=1 - CGO_ENABLED=1
overrides: overrides:
@@ -63,8 +96,8 @@ builds:
goarch: arm goarch: arm
goarm: 7 goarm: 7
env: env:
- CC=armv7a-linux-androideabi21-clang - CC=armv7a-linux-androideabi19-clang
- CXX=armv7a-linux-androideabi21-clang++ - CXX=armv7a-linux-androideabi19-clang++
- goos: android - goos: android
goarch: arm64 goarch: arm64
env: env:
@@ -73,8 +106,8 @@ builds:
- goos: android - goos: android
goarch: 386 goarch: 386
env: env:
- CC=i686-linux-android21-clang - CC=i686-linux-android19-clang
- CXX=i686-linux-android21-clang++ - CXX=i686-linux-android19-clang++
- goos: android - goos: android
goarch: amd64 goarch: amd64
goamd64: v1 goamd64: v1
@@ -86,11 +119,11 @@ builds:
- android_arm64 - android_arm64
- android_386 - android_386
- android_amd64 - android_amd64
mod_timestamp: '{{ .CommitTimestamp }}'
snapshot: snapshot:
name_template: "{{ .Version }}.{{ .ShortCommit }}" name_template: "{{ .Version }}.{{ .ShortCommit }}"
archives: archives:
- &template - id: archive
id: archive
builds: builds:
- main - main
- android - android
@@ -103,16 +136,21 @@ archives:
- LICENSE - LICENSE
name_template: '{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ with .Arm }}v{{ . }}{{ end }}{{ with .Mips }}_{{ . }}{{ end }}{{ if not (eq .Amd64 "v1") }}{{ .Amd64 }}{{ end }}' name_template: '{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ with .Arm }}v{{ . }}{{ end }}{{ with .Mips }}_{{ . }}{{ end }}{{ if not (eq .Amd64 "v1") }}{{ .Amd64 }}{{ end }}'
- id: archive-legacy - id: archive-legacy
<<: *template
builds: builds:
- legacy - legacy
format: tar.gz
format_overrides:
- goos: windows
format: zip
wrap_in_directory: true
files:
- LICENSE
name_template: '{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}-legacy' name_template: '{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}-legacy'
nfpms: nfpms:
- id: package - id: package
package_name: sing-box package_name: sing-box
file_name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ with .Arm }}v{{ . }}{{ end }}{{ with .Mips }}_{{ . }}{{ end }}{{ if not (eq .Amd64 "v1") }}{{ .Amd64 }}{{ end }}' file_name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ with .Arm }}v{{ . }}{{ end }}{{ with .Mips }}_{{ . }}{{ end }}{{ if not (eq .Amd64 "v1") }}{{ .Amd64 }}{{ end }}'
builds: vendor: sagernet
- main
homepage: https://sing-box.sagernet.org/ homepage: https://sing-box.sagernet.org/
maintainer: nekohasekai <contact-git@sekai.icu> maintainer: nekohasekai <contact-git@sekai.icu>
description: The universal proxy platform. description: The universal proxy platform.
@@ -127,27 +165,11 @@ nfpms:
dst: /etc/sing-box/config.json dst: /etc/sing-box/config.json
type: config type: config
- src: release/config/sing-box.service - src: release/config/sing-box.service
dst: /usr/lib/systemd/system/sing-box.service dst: /etc/systemd/system/sing-box.service
- src: release/config/sing-box@.service - src: release/config/sing-box@.service
dst: /usr/lib/systemd/system/sing-box@.service dst: /etc/systemd/system/sing-box@.service
- src: LICENSE - src: LICENSE
dst: /usr/share/licenses/sing-box/LICENSE dst: /usr/share/licenses/sing-box/LICENSE
deb:
signature:
key_file: "{{ .Env.NFPM_KEY_PATH }}"
fields:
Bugs: https://github.com/SagerNet/sing-box/issues
rpm:
signature:
key_file: "{{ .Env.NFPM_KEY_PATH }}"
overrides:
deb:
conflicts:
- sing-box-beta
rpm:
conflicts:
- sing-box-beta
source: source:
enabled: false enabled: false
name_template: '{{ .ProjectName }}-{{ .Version }}.source' name_template: '{{ .ProjectName }}-{{ .Version }}.source'
@@ -161,10 +183,6 @@ release:
github: github:
owner: SagerNet owner: SagerNet
name: sing-box name: sing-box
name_template: '{{ if .IsSnapshot }}{{ nightly }}{{ else }}{{ .Version }}{{ end }}'
draft: true draft: true
prerelease: auto mode: replace
mode: replace
ids:
- archive
- package
skip_upload: true

View File

@@ -1,4 +1,4 @@
FROM --platform=$BUILDPLATFORM golang:1.22-alpine AS builder FROM --platform=$BUILDPLATFORM golang:1.21-alpine AS builder
LABEL maintainer="nekohasekai <contact-git@sekai.icu>" LABEL maintainer="nekohasekai <contact-git@sekai.icu>"
COPY . /go/src/github.com/sagernet/sing-box COPY . /go/src/github.com/sagernet/sing-box
WORKDIR /go/src/github.com/sagernet/sing-box WORKDIR /go/src/github.com/sagernet/sing-box

View File

@@ -1,9 +1,8 @@
NAME = sing-box NAME = sing-box
COMMIT = $(shell git rev-parse --short HEAD) COMMIT = $(shell git rev-parse --short HEAD)
TAGS_GO118 = with_gvisor,with_dhcp,with_wireguard,with_reality_server,with_clash_api TAGS_GO118 = with_gvisor,with_dhcp,with_wireguard,with_reality_server,with_clash_api
TAGS_GO120 = with_quic,with_utls TAGS_GO120 = with_quic,with_ech,with_utls
TAGS_GO121 = with_ech TAGS ?= $(TAGS_GO118),$(TAGS_GO120)
TAGS ?= $(TAGS_GO118),$(TAGS_GO120),$(TAGS_GO121)
TAGS_TEST ?= with_gvisor,with_quic,with_wireguard,with_grpc,with_ech,with_utls,with_reality_server TAGS_TEST ?= with_gvisor,with_quic,with_wireguard,with_grpc,with_ech,with_utls,with_reality_server
GOHOSTOS = $(shell go env GOHOSTOS) GOHOSTOS = $(shell go env GOHOSTOS)
@@ -15,7 +14,7 @@ MAIN_PARAMS = $(PARAMS) -tags $(TAGS)
MAIN = ./cmd/sing-box MAIN = ./cmd/sing-box
PREFIX ?= $(shell go env GOPATH) PREFIX ?= $(shell go env GOPATH)
.PHONY: test release docs build .PHONY: test release docs
build: build:
go build $(MAIN_PARAMS) $(MAIN) go build $(MAIN_PARAMS) $(MAIN)
@@ -24,10 +23,6 @@ ci_build_go118:
go build $(PARAMS) $(MAIN) go build $(PARAMS) $(MAIN)
go build $(PARAMS) -tags "$(TAGS_GO118)" $(MAIN) go build $(PARAMS) -tags "$(TAGS_GO118)" $(MAIN)
ci_build_go120:
go build $(PARAMS) $(MAIN)
go build $(PARAMS) -tags "$(TAGS_GO118),$(TAGS_GO120)" $(MAIN)
ci_build: ci_build:
go build $(PARAMS) $(MAIN) go build $(PARAMS) $(MAIN)
go build $(MAIN_PARAMS) $(MAIN) go build $(MAIN_PARAMS) $(MAIN)
@@ -64,35 +59,25 @@ proto_install:
go install -v google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest go install -v google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
release: release:
go run ./cmd/internal/build goreleaser release --clean --skip publish go run ./cmd/internal/build goreleaser release --clean --skip-publish || exit 1
mkdir dist/release mkdir dist/release
mv dist/*.tar.gz \ mv dist/*.tar.gz dist/*.zip dist/*.deb dist/*.rpm dist/*.pkg.tar.zst dist/release
dist/*.zip \
dist/*.deb \
dist/*.rpm \
dist/*_amd64.pkg.tar.zst \
dist/*_amd64v3.pkg.tar.zst \
dist/*_arm64.pkg.tar.zst \
dist/release
ghr --replace --draft --prerelease -p 3 "v${VERSION}" dist/release ghr --replace --draft --prerelease -p 3 "v${VERSION}" dist/release
rm -r dist/release rm -r dist/release
release_repo:
go run ./cmd/internal/build goreleaser release -f .goreleaser.fury.yaml --clean
release_install: release_install:
go install -v github.com/goreleaser/goreleaser@latest
go install -v github.com/tcnksm/ghr@latest go install -v github.com/tcnksm/ghr@latest
update_android_version: update_android_version:
go run ./cmd/internal/update_android_version go run ./cmd/internal/update_android_version
build_android: build_android:
cd ../sing-box-for-android && ./gradlew :app:clean :app:assemblePlayRelease :app:assembleOtherRelease && ./gradlew --stop cd ../sing-box-for-android && ./gradlew :app:assemblePlayRelease && ./gradlew --stop
upload_android: upload_android:
mkdir -p dist/release_android mkdir -p dist/release_android
cp ../sing-box-for-android/app/build/outputs/apk/play/release/*.apk dist/release_android cp ../sing-box-for-android/app/build/outputs/apk/play/release/*.apk dist/release_android
cp ../sing-box-for-android/app/build/outputs/apk/other/release/*-universal.apk dist/release_android
ghr --replace --draft --prerelease -p 3 "v${VERSION}" dist/release_android ghr --replace --draft --prerelease -p 3 "v${VERSION}" dist/release_android
rm -rf dist/release_android rm -rf dist/release_android
@@ -193,8 +178,8 @@ lib:
go run ./cmd/internal/build_libbox -target ios go run ./cmd/internal/build_libbox -target ios
lib_install: lib_install:
go install -v github.com/sagernet/gomobile/cmd/gomobile@v0.1.3 go install -v github.com/sagernet/gomobile/cmd/gomobile@v0.1.1
go install -v github.com/sagernet/gomobile/cmd/gobind@v0.1.3 go install -v github.com/sagernet/gomobile/cmd/gobind@v0.1.1
docs: docs:
mkdocs serve mkdocs serve

View File

@@ -9,7 +9,6 @@ import (
"time" "time"
"github.com/sagernet/sing-box/common/urltest" "github.com/sagernet/sing-box/common/urltest"
"github.com/sagernet/sing-dns"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/rw" "github.com/sagernet/sing/common/rw"
) )
@@ -31,9 +30,6 @@ type CacheFile interface {
StoreFakeIP() bool StoreFakeIP() bool
FakeIPStorage FakeIPStorage
StoreRDRC() bool
dns.RDRCStore
LoadMode() string LoadMode() string
StoreMode(mode string) error StoreMode(mode string) error
LoadSelected(group string) string LoadSelected(group string) string

View File

@@ -51,13 +51,11 @@ type InboundContext struct {
// rule cache // rule cache
IPCIDRMatchSource bool IPCIDRMatchSource bool
SourceAddressMatch bool SourceAddressMatch bool
SourcePortMatch bool SourcePortMatch bool
DestinationAddressMatch bool DestinationAddressMatch bool
DestinationPortMatch bool DestinationPortMatch bool
DidMatch bool
IgnoreDestinationIPCIDRMatch bool
} }
func (c *InboundContext) ResetRuleCache() { func (c *InboundContext) ResetRuleCache() {
@@ -66,7 +64,6 @@ func (c *InboundContext) ResetRuleCache() {
c.SourcePortMatch = false c.SourcePortMatch = false
c.DestinationAddressMatch = false c.DestinationAddressMatch = false
c.DestinationPortMatch = false c.DestinationPortMatch = false
c.DidMatch = false
} }
type inboundContextKey struct{} type inboundContextKey struct{}
@@ -99,12 +96,3 @@ func ExtendContext(ctx context.Context) (context.Context, *InboundContext) {
} }
return WithContext(ctx, &newMetadata), &newMetadata return WithContext(ctx, &newMetadata), &newMetadata
} }
func OverrideContext(ctx context.Context) context.Context {
if metadata := ContextFrom(ctx); metadata != nil {
var newMetadata InboundContext
newMetadata = *metadata
return WithContext(ctx, &newMetadata)
}
return ctx
}

View File

@@ -17,7 +17,6 @@ import (
type Router interface { type Router interface {
Service Service
PreStarter
PostStarter PostStarter
Outbounds() []Outbound Outbounds() []Outbound
@@ -33,8 +32,6 @@ type Router interface {
RuleSet(tag string) (RuleSet, bool) RuleSet(tag string) (RuleSet, bool)
NeedWIFIState() bool
Exchange(ctx context.Context, message *mdns.Msg) (*mdns.Msg, error) Exchange(ctx context.Context, message *mdns.Msg) (*mdns.Msg, error)
Lookup(ctx context.Context, domain string, strategy dns.DomainStrategy) ([]netip.Addr, error) Lookup(ctx context.Context, domain string, strategy dns.DomainStrategy) ([]netip.Addr, error)
LookupDefault(ctx context.Context, domain string) ([]netip.Addr, error) LookupDefault(ctx context.Context, domain string) ([]netip.Addr, error)
@@ -71,7 +68,6 @@ func RouterFromContext(ctx context.Context) Router {
type HeadlessRule interface { type HeadlessRule interface {
Match(metadata *InboundContext) bool Match(metadata *InboundContext) bool
String() string
} }
type Rule interface { type Rule interface {
@@ -80,19 +76,18 @@ type Rule interface {
Type() string Type() string
UpdateGeosite() error UpdateGeosite() error
Outbound() string Outbound() string
String() string
} }
type DNSRule interface { type DNSRule interface {
Rule Rule
DisableCache() bool DisableCache() bool
RewriteTTL() *uint32 RewriteTTL() *uint32
ClientSubnet() *netip.Prefix
WithAddressLimit() bool
MatchAddressLimit(metadata *InboundContext) bool
} }
type RuleSet interface { type RuleSet interface {
StartContext(ctx context.Context, startContext RuleSetStartContext) error StartContext(ctx context.Context, startContext RuleSetStartContext) error
PostStart() error
Metadata() RuleSetMetadata Metadata() RuleSetMetadata
Close() error Close() error
HeadlessRule HeadlessRule
@@ -101,7 +96,6 @@ type RuleSet interface {
type RuleSetMetadata struct { type RuleSetMetadata struct {
ContainsProcessRule bool ContainsProcessRule bool
ContainsWIFIRule bool ContainsWIFIRule bool
ContainsIPCIDRRule bool
} }
type RuleSetStartContext interface { type RuleSetStartContext interface {

22
box.go
View File

@@ -55,7 +55,7 @@ func New(options Options) (*Box, error) {
ctx = context.Background() ctx = context.Background()
} }
ctx = service.ContextWithDefaultRegistry(ctx) ctx = service.ContextWithDefaultRegistry(ctx)
ctx = pause.WithDefaultManager(ctx) ctx = pause.ContextWithDefaultManager(ctx)
experimentalOptions := common.PtrValueOrDefault(options.Experimental) experimentalOptions := common.PtrValueOrDefault(options.Experimental)
applyDebugOptions(common.PtrValueOrDefault(experimentalOptions.Debug)) applyDebugOptions(common.PtrValueOrDefault(experimentalOptions.Debug))
var needCacheFile bool var needCacheFile bool
@@ -157,12 +157,9 @@ func New(options Options) (*Box, error) {
preServices2 := make(map[string]adapter.Service) preServices2 := make(map[string]adapter.Service)
postServices := make(map[string]adapter.Service) postServices := make(map[string]adapter.Service)
if needCacheFile { if needCacheFile {
cacheFile := service.FromContext[adapter.CacheFile](ctx) cacheFile := cachefile.New(ctx, common.PtrValueOrDefault(experimentalOptions.CacheFile))
if cacheFile == nil {
cacheFile = cachefile.New(ctx, common.PtrValueOrDefault(experimentalOptions.CacheFile))
service.MustRegister[adapter.CacheFile](ctx, cacheFile)
}
preServices1["cache file"] = cacheFile preServices1["cache file"] = cacheFile
service.MustRegister[adapter.CacheFile](ctx, cacheFile)
} }
if needClashAPI { if needClashAPI {
clashAPIOptions := common.PtrValueOrDefault(experimentalOptions.ClashAPI) clashAPIOptions := common.PtrValueOrDefault(experimentalOptions.ClashAPI)
@@ -235,7 +232,7 @@ func (s *Box) Start() error {
} }
func (s *Box) preStart() error { func (s *Box) preStart() error {
monitor := taskmonitor.New(s.logger, C.StartTimeout) monitor := taskmonitor.New(s.logger, C.DefaultStartTimeout)
monitor.Start("start logger") monitor.Start("start logger")
err := s.logFactory.Start() err := s.logFactory.Start()
monitor.Finish() monitor.Finish()
@@ -262,10 +259,6 @@ func (s *Box) preStart() error {
} }
} }
} }
err = s.router.PreStart()
if err != nil {
return E.Cause(err, "pre-start router")
}
err = s.startOutbounds() err = s.startOutbounds()
if err != nil { if err != nil {
return err return err
@@ -320,7 +313,10 @@ func (s *Box) postStart() error {
} }
} }
} }
err := s.router.PostStart()
if err != nil {
return E.Cause(err, "post-start router")
}
return s.router.PostStart() return s.router.PostStart()
} }
@@ -331,7 +327,7 @@ func (s *Box) Close() error {
default: default:
close(s.done) close(s.done)
} }
monitor := taskmonitor.New(s.logger, C.StopTimeout) monitor := taskmonitor.New(s.logger, C.DefaultStopTimeout)
var errors error var errors error
for serviceName, service := range s.postServices { for serviceName, service := range s.postServices {
monitor.Start("close ", serviceName) monitor.Start("close ", serviceName)

View File

@@ -12,7 +12,7 @@ import (
) )
func (s *Box) startOutbounds() error { func (s *Box) startOutbounds() error {
monitor := taskmonitor.New(s.logger, C.StartTimeout) monitor := taskmonitor.New(s.logger, C.DefaultStartTimeout)
outboundTags := make(map[adapter.Outbound]string) outboundTags := make(map[adapter.Outbound]string)
outbounds := make(map[string]adapter.Outbound) outbounds := make(map[string]adapter.Outbound)
for i, outboundToStart := range s.outbounds { for i, outboundToStart := range s.outbounds {

Submodule clients/android deleted from 8622e6a5bc

Submodule clients/apple deleted from 0cbe335cbb

View File

@@ -46,13 +46,13 @@ var (
func init() { func init() {
sharedFlags = append(sharedFlags, "-trimpath") sharedFlags = append(sharedFlags, "-trimpath")
sharedFlags = append(sharedFlags, "-buildvcs=false") sharedFlags = append(sharedFlags, "-ldflags")
currentTag, err := build_shared.ReadTag() currentTag, err := build_shared.ReadTag()
if err != nil { if err != nil {
currentTag = "unknown" currentTag = "unknown"
} }
sharedFlags = append(sharedFlags, "-ldflags", "-X github.com/sagernet/sing-box/constant.Version="+currentTag+" -s -w -buildid=") sharedFlags = append(sharedFlags, "-X github.com/sagernet/sing-box/constant.Version="+currentTag+" -s -w -buildid=")
debugFlags = append(debugFlags, "-ldflags", "-X github.com/sagernet/sing-box/constant.Version="+currentTag) debugFlags = append(debugFlags, "-X github.com/sagernet/sing-box/constant.Version="+currentTag)
sharedTags = append(sharedTags, "with_gvisor", "with_quic", "with_wireguard", "with_ech", "with_utls", "with_clash_api") sharedTags = append(sharedTags, "with_gvisor", "with_quic", "with_wireguard", "with_ech", "with_utls", "with_clash_api")
iosTags = append(iosTags, "with_dhcp", "with_low_memory", "with_conntrack") iosTags = append(iosTags, "with_dhcp", "with_low_memory", "with_conntrack")

View File

@@ -11,9 +11,7 @@ import (
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/rw" "github.com/sagernet/sing/common/rw"
"github.com/sagernet/sing/common/shell"
) )
var ( var (
@@ -30,7 +28,7 @@ func FindSDK() {
} }
for _, path := range searchPath { for _, path := range searchPath {
path = os.ExpandEnv(path) path = os.ExpandEnv(path)
if rw.FileExists(filepath.Join(path, "licenses", "android-sdk-license")) { if rw.FileExists(path + "/licenses/android-sdk-license") {
androidSDKPath = path androidSDKPath = path
break break
} }
@@ -42,14 +40,6 @@ func FindSDK() {
log.Fatal("android NDK not found") log.Fatal("android NDK not found")
} }
javaVersion, err := shell.Exec("java", "--version").ReadOutput()
if err != nil {
log.Fatal(E.Cause(err, "check java version"))
}
if !strings.Contains(javaVersion, "openjdk 17") {
log.Fatal("java version should be openjdk 17")
}
os.Setenv("ANDROID_HOME", androidSDKPath) os.Setenv("ANDROID_HOME", androidSDKPath)
os.Setenv("ANDROID_SDK_HOME", androidSDKPath) os.Setenv("ANDROID_SDK_HOME", androidSDKPath)
os.Setenv("ANDROID_NDK_HOME", androidNDKPath) os.Setenv("ANDROID_NDK_HOME", androidNDKPath)
@@ -58,13 +48,11 @@ func FindSDK() {
} }
func findNDK() bool { func findNDK() bool {
const fixedVersion = "26.2.11394342" if rw.FileExists(androidSDKPath + "/ndk/25.1.8937393") {
const versionFile = "source.properties" androidNDKPath = androidSDKPath + "/ndk/25.1.8937393"
if fixedPath := filepath.Join(androidSDKPath, "ndk", fixedVersion); rw.FileExists(filepath.Join(fixedPath, versionFile)) {
androidNDKPath = fixedPath
return true return true
} }
ndkVersions, err := os.ReadDir(filepath.Join(androidSDKPath, "ndk")) ndkVersions, err := os.ReadDir(androidSDKPath + "/ndk")
if err != nil { if err != nil {
return false return false
} }
@@ -85,10 +73,8 @@ func findNDK() bool {
return true return true
}) })
for _, versionName := range versionNames { for _, versionName := range versionNames {
currentNDKPath := filepath.Join(androidSDKPath, "ndk", versionName) if rw.FileExists(androidSDKPath + "/ndk/" + versionName) {
if rw.FileExists(filepath.Join(androidSDKPath, versionFile)) { androidNDKPath = androidSDKPath + "/ndk/" + versionName
androidNDKPath = currentNDKPath
log.Warn("reproducibility warning: using NDK version " + versionName + " instead of " + fixedVersion)
return true return true
} }
} }
@@ -99,14 +85,8 @@ var GoBinPath string
func FindMobile() { func FindMobile() {
goBin := filepath.Join(build.Default.GOPATH, "bin") goBin := filepath.Join(build.Default.GOPATH, "bin")
if runtime.GOOS == "windows" { if !rw.FileExists(goBin + "/" + "gobind") {
if !rw.FileExists(filepath.Join(goBin, "gobind.exe")) { log.Fatal("missing gomobile installation")
log.Fatal("missing gomobile installation")
}
} else {
if !rw.FileExists(filepath.Join(goBin, "gobind")) {
log.Fatal("missing gomobile installation")
}
} }
GoBinPath = goBin GoBinPath = goBin
} }

View File

@@ -3,7 +3,6 @@ package main
import ( import (
"os" "os"
"path/filepath" "path/filepath"
"runtime"
"strconv" "strconv"
"strings" "strings"
@@ -19,46 +18,34 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
common.Must(os.Chdir(androidPath)) common.Must(os.Chdir(androidPath))
localProps := common.Must1(os.ReadFile("version.properties")) localProps := common.Must1(os.ReadFile("local.properties"))
var propsList [][]string var propsList [][]string
for _, propLine := range strings.Split(string(localProps), "\n") { for _, propLine := range strings.Split(string(localProps), "\n") {
propsList = append(propsList, strings.Split(propLine, "=")) propsList = append(propsList, strings.Split(propLine, "="))
} }
var (
versionUpdated bool
goVersionUpdated bool
)
for _, propPair := range propsList { for _, propPair := range propsList {
switch propPair[0] { if propPair[0] == "VERSION_NAME" {
case "VERSION_NAME": if propPair[1] == newVersion.String() {
if propPair[1] != newVersion.String() { log.Info("version not changed")
versionUpdated = true return
propPair[1] = newVersion.String()
log.Info("updated version to ", newVersion.String())
}
case "GO_VERSION":
if propPair[1] != runtime.Version() {
goVersionUpdated = true
propPair[1] = runtime.Version()
log.Info("updated Go version to ", runtime.Version())
} }
propPair[1] = newVersion.String()
log.Info("updated version to ", newVersion.String())
} }
} }
if !(versionUpdated || goVersionUpdated) {
log.Info("version not changed")
return
}
for _, propPair := range propsList { for _, propPair := range propsList {
switch propPair[0] { switch propPair[0] {
case "VERSION_CODE": case "VERSION_CODE":
versionCode := common.Must1(strconv.ParseInt(propPair[1], 10, 64)) versionCode := common.Must1(strconv.ParseInt(propPair[1], 10, 64))
propPair[1] = strconv.Itoa(int(versionCode + 1)) propPair[1] = strconv.Itoa(int(versionCode + 1))
log.Info("updated version code to ", propPair[1]) log.Info("updated version code to ", propPair[1])
case "RELEASE_NOTES":
propPair[1] = "sing-box " + newVersion.String()
} }
} }
var newProps []string var newProps []string
for _, propPair := range propsList { for _, propPair := range propsList {
newProps = append(newProps, strings.Join(propPair, "=")) newProps = append(newProps, strings.Join(propPair, "="))
} }
common.Must(os.WriteFile("version.properties", []byte(strings.Join(newProps, "\n")), 0o644)) common.Must(os.WriteFile("local.properties", []byte(strings.Join(newProps, "\n")), 0o644))
} }

View File

@@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/json"
"io" "io"
"os" "os"
@@ -8,7 +9,6 @@ import (
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common/json"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View File

@@ -47,14 +47,10 @@ func compileRuleSet(sourcePath string) error {
return err return err
} }
} }
content, err := io.ReadAll(reader) decoder := json.NewDecoder(json.NewCommentFilter(reader))
if err != nil { decoder.DisallowUnknownFields()
return err var plainRuleSet option.PlainRuleSetCompat
} err = decoder.Decode(&plainRuleSet)
plainRuleSet, err := json.UnmarshalExtended[option.PlainRuleSetCompat](content)
if err != nil {
return err
}
if err != nil { if err != nil {
return err return err
} }

View File

@@ -50,14 +50,18 @@ func formatRuleSet(sourcePath string) error {
if err != nil { if err != nil {
return err return err
} }
plainRuleSet, err := json.UnmarshalExtended[option.PlainRuleSetCompat](content) decoder := json.NewDecoder(json.NewCommentFilter(bytes.NewReader(content)))
decoder.DisallowUnknownFields()
var plainRuleSet option.PlainRuleSetCompat
err = decoder.Decode(&plainRuleSet)
if err != nil { if err != nil {
return err return err
} }
ruleSet := plainRuleSet.Upgrade()
buffer := new(bytes.Buffer) buffer := new(bytes.Buffer)
encoder := json.NewEncoder(buffer) encoder := json.NewEncoder(buffer)
encoder.SetIndent("", " ") encoder.SetIndent("", " ")
err = encoder.Encode(plainRuleSet) err = encoder.Encode(ruleSet)
if err != nil { if err != nil {
return E.Cause(err, "encode config") return E.Cause(err, "encode config")
} }

View File

@@ -1,86 +0,0 @@
package main
import (
"bytes"
"io"
"os"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/srs"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/route"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/json"
"github.com/spf13/cobra"
)
var flagRuleSetMatchFormat string
var commandRuleSetMatch = &cobra.Command{
Use: "match <rule-set path> <domain>",
Short: "Check if a domain matches the rule set",
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
err := ruleSetMatch(args[0], args[1])
if err != nil {
log.Fatal(err)
}
},
}
func init() {
commandRuleSetMatch.Flags().StringVarP(&flagRuleSetMatchFormat, "format", "f", "source", "rule-set format")
commandRuleSet.AddCommand(commandRuleSetMatch)
}
func ruleSetMatch(sourcePath string, domain string) error {
var (
reader io.Reader
err error
)
if sourcePath == "stdin" {
reader = os.Stdin
} else {
reader, err = os.Open(sourcePath)
if err != nil {
return E.Cause(err, "read rule-set")
}
}
content, err := io.ReadAll(reader)
if err != nil {
return E.Cause(err, "read rule-set")
}
var plainRuleSet option.PlainRuleSet
switch flagRuleSetMatchFormat {
case C.RuleSetFormatSource:
var compat option.PlainRuleSetCompat
compat, err = json.UnmarshalExtended[option.PlainRuleSetCompat](content)
if err != nil {
return err
}
plainRuleSet = compat.Upgrade()
case C.RuleSetFormatBinary:
plainRuleSet, err = srs.Read(bytes.NewReader(content), false)
if err != nil {
return err
}
default:
return E.New("unknown rule set format: ", flagRuleSetMatchFormat)
}
for i, ruleOptions := range plainRuleSet.Rules {
var currentRule adapter.HeadlessRule
currentRule, err = route.NewHeadlessRule(nil, ruleOptions)
if err != nil {
return E.Cause(err, "parse rule_set.rules.[", i, "]")
}
if currentRule.Match(&adapter.InboundContext{
Domain: domain,
}) {
println("match rules.[", i, "]: "+currentRule.String())
}
}
return nil
}

View File

@@ -57,7 +57,8 @@ func readConfigAt(path string) (*OptionsEntry, error) {
if err != nil { if err != nil {
return nil, E.Cause(err, "read config at ", path) return nil, E.Cause(err, "read config at ", path)
} }
options, err := json.UnmarshalExtended[option.Options](configContent) var options option.Options
err = options.UnmarshalJSON(configContent)
if err != nil { if err != nil {
return nil, E.Cause(err, "decode config at ", path) return nil, E.Cause(err, "decode config at ", path)
} }
@@ -133,7 +134,7 @@ func create() (*box.Box, context.CancelFunc, error) {
} }
options.Log.DisableColor = true options.Log.DisableColor = true
} }
ctx, cancel := context.WithCancel(globalCtx) ctx, cancel := context.WithCancel(context.Background())
instance, err := box.New(box.Options{ instance, err := box.New(box.Options{
Context: ctx, Context: ctx,
Options: options, Options: options,
@@ -199,7 +200,7 @@ func run() error {
} }
func closeMonitor(ctx context.Context) { func closeMonitor(ctx context.Context) {
time.Sleep(C.FatalStopTimeout) time.Sleep(C.DefaultStopFatalTimeout)
select { select {
case <-ctx.Done(): case <-ctx.Done():
return return

View File

@@ -3,19 +3,15 @@ package main
import ( import (
"context" "context"
"os" "os"
"os/user"
"strconv"
"time" "time"
_ "github.com/sagernet/sing-box/include" _ "github.com/sagernet/sing-box/include"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/service/filemanager"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var ( var (
globalCtx context.Context
configPaths []string configPaths []string
configDirectories []string configDirectories []string
workingDir string workingDir string
@@ -41,30 +37,15 @@ func main() {
} }
func preRun(cmd *cobra.Command, args []string) { func preRun(cmd *cobra.Command, args []string) {
globalCtx = context.Background()
sudoUser := os.Getenv("SUDO_USER")
sudoUID, _ := strconv.Atoi(os.Getenv("SUDO_UID"))
sudoGID, _ := strconv.Atoi(os.Getenv("SUDO_GID"))
if sudoUID == 0 && sudoGID == 0 && sudoUser != "" {
sudoUserObject, _ := user.Lookup(sudoUser)
if sudoUserObject != nil {
sudoUID, _ = strconv.Atoi(sudoUserObject.Uid)
sudoGID, _ = strconv.Atoi(sudoUserObject.Gid)
}
}
if sudoUID > 0 && sudoGID > 0 {
globalCtx = filemanager.WithDefault(globalCtx, "", "", sudoUID, sudoGID)
}
if disableColor { if disableColor {
log.SetStdLogger(log.NewDefaultFactory(context.Background(), log.Formatter{BaseTime: time.Now(), DisableColors: true}, os.Stderr, "", nil, false).Logger()) log.SetStdLogger(log.NewDefaultFactory(context.Background(), log.Formatter{BaseTime: time.Now(), DisableColors: true}, os.Stderr, "", nil, false).Logger())
} }
if workingDir != "" { if workingDir != "" {
_, err := os.Stat(workingDir) _, err := os.Stat(workingDir)
if err != nil { if err != nil {
filemanager.MkdirAll(globalCtx, workingDir, 0o777) os.MkdirAll(workingDir, 0o777)
} }
err = os.Chdir(workingDir) if err := os.Chdir(workingDir); err != nil {
if err != nil {
log.Fatal(err) log.Fatal(err)
} }
} }

View File

@@ -4,8 +4,6 @@ package badtls
import ( import (
"bytes" "bytes"
"context"
"net"
"os" "os"
"reflect" "reflect"
"sync" "sync"
@@ -20,32 +18,20 @@ import (
var _ N.ReadWaiter = (*ReadWaitConn)(nil) var _ N.ReadWaiter = (*ReadWaitConn)(nil)
type ReadWaitConn struct { type ReadWaitConn struct {
tls.Conn *tls.STDConn
halfAccess *sync.Mutex halfAccess *sync.Mutex
rawInput *bytes.Buffer rawInput *bytes.Buffer
input *bytes.Reader input *bytes.Reader
hand *bytes.Buffer hand *bytes.Buffer
readWaitOptions N.ReadWaitOptions readWaitOptions N.ReadWaitOptions
tlsReadRecord func() error
tlsHandlePostHandshakeMessage func() error
} }
func NewReadWaitConn(conn tls.Conn) (tls.Conn, error) { func NewReadWaitConn(conn tls.Conn) (tls.Conn, error) {
var ( stdConn, isSTDConn := conn.(*tls.STDConn)
loaded bool if !isSTDConn {
tlsReadRecord func() error
tlsHandlePostHandshakeMessage func() error
)
for _, tlsCreator := range tlsRegistry {
loaded, tlsReadRecord, tlsHandlePostHandshakeMessage = tlsCreator(conn)
if loaded {
break
}
}
if !loaded {
return nil, os.ErrInvalid return nil, os.ErrInvalid
} }
rawConn := reflect.Indirect(reflect.ValueOf(conn)) rawConn := reflect.Indirect(reflect.ValueOf(stdConn))
rawHalfConn := rawConn.FieldByName("in") rawHalfConn := rawConn.FieldByName("in")
if !rawHalfConn.IsValid() || rawHalfConn.Kind() != reflect.Struct { if !rawHalfConn.IsValid() || rawHalfConn.Kind() != reflect.Struct {
return nil, E.New("badtls: invalid half conn") return nil, E.New("badtls: invalid half conn")
@@ -71,13 +57,11 @@ func NewReadWaitConn(conn tls.Conn) (tls.Conn, error) {
} }
hand := (*bytes.Buffer)(unsafe.Pointer(rawHand.UnsafeAddr())) hand := (*bytes.Buffer)(unsafe.Pointer(rawHand.UnsafeAddr()))
return &ReadWaitConn{ return &ReadWaitConn{
Conn: conn, STDConn: stdConn,
halfAccess: halfAccess, halfAccess: halfAccess,
rawInput: rawInput, rawInput: rawInput,
input: input, input: input,
hand: hand, hand: hand,
tlsReadRecord: tlsReadRecord,
tlsHandlePostHandshakeMessage: tlsHandlePostHandshakeMessage,
}, nil }, nil
} }
@@ -87,19 +71,19 @@ func (c *ReadWaitConn) InitializeReadWaiter(options N.ReadWaitOptions) (needCopy
} }
func (c *ReadWaitConn) WaitReadBuffer() (buffer *buf.Buffer, err error) { func (c *ReadWaitConn) WaitReadBuffer() (buffer *buf.Buffer, err error) {
err = c.HandshakeContext(context.Background()) err = c.Handshake()
if err != nil { if err != nil {
return return
} }
c.halfAccess.Lock() c.halfAccess.Lock()
defer c.halfAccess.Unlock() defer c.halfAccess.Unlock()
for c.input.Len() == 0 { for c.input.Len() == 0 {
err = c.tlsReadRecord() err = tlsReadRecord(c.STDConn)
if err != nil { if err != nil {
return return
} }
for c.hand.Len() > 0 { for c.hand.Len() > 0 {
err = c.tlsHandlePostHandshakeMessage() err = tlsHandlePostHandshakeMessage(c.STDConn)
if err != nil { if err != nil {
return return
} }
@@ -116,7 +100,7 @@ func (c *ReadWaitConn) WaitReadBuffer() (buffer *buf.Buffer, err error) {
if n != 0 && c.input.Len() == 0 && c.rawInput.Len() > 0 && if n != 0 && c.input.Len() == 0 && c.rawInput.Len() > 0 &&
// recordType(c.rawInput.Bytes()[0]) == recordTypeAlert { // recordType(c.rawInput.Bytes()[0]) == recordTypeAlert {
c.rawInput.Bytes()[0] == 21 { c.rawInput.Bytes()[0] == 21 {
_ = c.tlsReadRecord() _ = tlsReadRecord(c.STDConn)
// return n, err // will be io.EOF on closeNotify // return n, err // will be io.EOF on closeNotify
} }
@@ -124,28 +108,8 @@ func (c *ReadWaitConn) WaitReadBuffer() (buffer *buf.Buffer, err error) {
return return
} }
func (c *ReadWaitConn) Upstream() any { //go:linkname tlsReadRecord crypto/tls.(*Conn).readRecord
return c.Conn func tlsReadRecord(c *tls.STDConn) error
}
var tlsRegistry []func(conn net.Conn) (loaded bool, tlsReadRecord func() error, tlsHandlePostHandshakeMessage func() error) //go:linkname tlsHandlePostHandshakeMessage crypto/tls.(*Conn).handlePostHandshakeMessage
func tlsHandlePostHandshakeMessage(c *tls.STDConn) error
func init() {
tlsRegistry = append(tlsRegistry, func(conn net.Conn) (loaded bool, tlsReadRecord func() error, tlsHandlePostHandshakeMessage func() error) {
tlsConn, loaded := conn.(*tls.STDConn)
if !loaded {
return
}
return true, func() error {
return stdTLSReadRecord(tlsConn)
}, func() error {
return stdTLSHandlePostHandshakeMessage(tlsConn)
}
})
}
//go:linkname stdTLSReadRecord crypto/tls.(*Conn).readRecord
func stdTLSReadRecord(c *tls.STDConn) error
//go:linkname stdTLSHandlePostHandshakeMessage crypto/tls.(*Conn).handlePostHandshakeMessage
func stdTLSHandlePostHandshakeMessage(c *tls.STDConn) error

View File

@@ -1,31 +0,0 @@
//go:build go1.21 && !without_badtls && with_ech
package badtls
import (
"net"
_ "unsafe"
"github.com/sagernet/cloudflare-tls"
"github.com/sagernet/sing/common"
)
func init() {
tlsRegistry = append(tlsRegistry, func(conn net.Conn) (loaded bool, tlsReadRecord func() error, tlsHandlePostHandshakeMessage func() error) {
tlsConn, loaded := common.Cast[*tls.Conn](conn)
if !loaded {
return
}
return true, func() error {
return echReadRecord(tlsConn)
}, func() error {
return echHandlePostHandshakeMessage(tlsConn)
}
})
}
//go:linkname echReadRecord github.com/sagernet/cloudflare-tls.(*Conn).readRecord
func echReadRecord(c *tls.Conn) error
//go:linkname echHandlePostHandshakeMessage github.com/sagernet/cloudflare-tls.(*Conn).handlePostHandshakeMessage
func echHandlePostHandshakeMessage(c *tls.Conn) error

View File

@@ -1,31 +0,0 @@
//go:build go1.21 && !without_badtls && with_utls
package badtls
import (
"net"
_ "unsafe"
"github.com/sagernet/sing/common"
"github.com/sagernet/utls"
)
func init() {
tlsRegistry = append(tlsRegistry, func(conn net.Conn) (loaded bool, tlsReadRecord func() error, tlsHandlePostHandshakeMessage func() error) {
tlsConn, loaded := common.Cast[*tls.UConn](conn)
if !loaded {
return
}
return true, func() error {
return utlsReadRecord(tlsConn.Conn)
}, func() error {
return utlsHandlePostHandshakeMessage(tlsConn.Conn)
}
})
}
//go:linkname utlsReadRecord github.com/sagernet/utls.(*Conn).readRecord
func utlsReadRecord(c *tls.Conn) error
//go:linkname utlsHandlePostHandshakeMessage github.com/sagernet/utls.(*Conn).handlePostHandshakeMessage
func utlsHandlePostHandshakeMessage(c *tls.Conn) error

View File

@@ -15,37 +15,28 @@ import (
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
) )
var _ WireGuardListener = (*DefaultDialer)(nil)
type DefaultDialer struct { type DefaultDialer struct {
dialer4 tcpDialer dialer4 tcpDialer
dialer6 tcpDialer dialer6 tcpDialer
udpDialer4 net.Dialer udpDialer4 net.Dialer
udpDialer6 net.Dialer udpDialer6 net.Dialer
udpListener net.ListenConfig udpListener net.ListenConfig
udpAddr4 string udpAddr4 string
udpAddr6 string udpAddr6 string
isWireGuardListener bool
} }
func NewDefault(router adapter.Router, options option.DialerOptions) (*DefaultDialer, error) { func NewDefault(router adapter.Router, options option.DialerOptions) (*DefaultDialer, error) {
var dialer net.Dialer var dialer net.Dialer
var listener net.ListenConfig var listener net.ListenConfig
if options.BindInterface != "" { if options.BindInterface != "" {
var interfaceFinder control.InterfaceFinder bindFunc := control.BindToInterface(router.InterfaceFinder(), options.BindInterface, -1)
if router != nil {
interfaceFinder = router.InterfaceFinder()
} else {
interfaceFinder = control.NewDefaultInterfaceFinder()
}
bindFunc := control.BindToInterface(interfaceFinder, options.BindInterface, -1)
dialer.Control = control.Append(dialer.Control, bindFunc) dialer.Control = control.Append(dialer.Control, bindFunc)
listener.Control = control.Append(listener.Control, bindFunc) listener.Control = control.Append(listener.Control, bindFunc)
} else if router != nil && router.AutoDetectInterface() { } else if router.AutoDetectInterface() {
bindFunc := router.AutoDetectInterfaceFunc() bindFunc := router.AutoDetectInterfaceFunc()
dialer.Control = control.Append(dialer.Control, bindFunc) dialer.Control = control.Append(dialer.Control, bindFunc)
listener.Control = control.Append(listener.Control, bindFunc) listener.Control = control.Append(listener.Control, bindFunc)
} else if router != nil && router.DefaultInterface() != "" { } else if router.DefaultInterface() != "" {
bindFunc := control.BindToInterface(router.InterfaceFinder(), router.DefaultInterface(), -1) bindFunc := control.BindToInterface(router.InterfaceFinder(), router.DefaultInterface(), -1)
dialer.Control = control.Append(dialer.Control, bindFunc) dialer.Control = control.Append(dialer.Control, bindFunc)
listener.Control = control.Append(listener.Control, bindFunc) listener.Control = control.Append(listener.Control, bindFunc)
@@ -53,7 +44,7 @@ func NewDefault(router adapter.Router, options option.DialerOptions) (*DefaultDi
if options.RoutingMark != 0 { if options.RoutingMark != 0 {
dialer.Control = control.Append(dialer.Control, control.RoutingMark(options.RoutingMark)) dialer.Control = control.Append(dialer.Control, control.RoutingMark(options.RoutingMark))
listener.Control = control.Append(listener.Control, control.RoutingMark(options.RoutingMark)) listener.Control = control.Append(listener.Control, control.RoutingMark(options.RoutingMark))
} else if router != nil && router.DefaultMark() != 0 { } else if router.DefaultMark() != 0 {
dialer.Control = control.Append(dialer.Control, control.RoutingMark(router.DefaultMark())) dialer.Control = control.Append(dialer.Control, control.RoutingMark(router.DefaultMark()))
listener.Control = control.Append(listener.Control, control.RoutingMark(router.DefaultMark())) listener.Control = control.Append(listener.Control, control.RoutingMark(router.DefaultMark()))
} }
@@ -69,9 +60,6 @@ func NewDefault(router adapter.Router, options option.DialerOptions) (*DefaultDi
} else { } else {
dialer.Timeout = C.TCPTimeout dialer.Timeout = C.TCPTimeout
} }
// TODO: Add an option to customize the keep alive period
dialer.KeepAlive = C.TCPKeepAliveInitial
dialer.Control = control.Append(dialer.Control, control.SetKeepAlivePeriod(C.TCPKeepAliveInitial, C.TCPKeepAliveInterval))
var udpFragment bool var udpFragment bool
if options.UDPFragment != nil { if options.UDPFragment != nil {
udpFragment = *options.UDPFragment udpFragment = *options.UDPFragment
@@ -110,11 +98,6 @@ func NewDefault(router adapter.Router, options option.DialerOptions) (*DefaultDi
} }
setMultiPathTCP(&dialer4) setMultiPathTCP(&dialer4)
} }
if options.IsWireGuardListener {
for _, controlFn := range wgControlFns {
listener.Control = control.Append(listener.Control, controlFn)
}
}
tcpDialer4, err := newTCPDialer(dialer4, options.TCPFastOpen) tcpDialer4, err := newTCPDialer(dialer4, options.TCPFastOpen)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -131,7 +114,6 @@ func NewDefault(router adapter.Router, options option.DialerOptions) (*DefaultDi
listener, listener,
udpAddr4, udpAddr4,
udpAddr6, udpAddr6,
options.IsWireGuardListener,
}, nil }, nil
} }
@@ -164,10 +146,6 @@ func (d *DefaultDialer) ListenPacket(ctx context.Context, destination M.Socksadd
} }
} }
func (d *DefaultDialer) ListenPacketCompat(network, address string) (net.PacketConn, error) {
return trackPacketConn(d.udpListener.ListenPacket(context.Background(), network, address))
}
func trackConn(conn net.Conn, err error) (net.Conn, error) { func trackConn(conn net.Conn, err error) (net.Conn, error) {
if !conntrack.Enabled || err != nil { if !conntrack.Enabled || err != nil {
return conn, err return conn, err

View File

@@ -6,16 +6,15 @@ import (
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-dns" "github.com/sagernet/sing-dns"
"github.com/sagernet/sing/common"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
) )
func MustNew(router adapter.Router, options option.DialerOptions) N.Dialer {
return common.Must1(New(router, options))
}
func New(router adapter.Router, options option.DialerOptions) (N.Dialer, error) { func New(router adapter.Router, options option.DialerOptions) (N.Dialer, error) {
if options.IsWireGuardListener {
return NewDefault(router, options)
}
if router == nil {
return NewDefault(nil, options)
}
var ( var (
dialer N.Dialer dialer N.Dialer
err error err error

View File

@@ -80,7 +80,6 @@ func (c *slowOpenConn) Write(b []byte) (n int, err error) {
c.conn = nil c.conn = nil
c.err = E.Cause(err, "dial tcp fast open") c.err = E.Cause(err, "dial tcp fast open")
} }
n = len(b)
close(c.create) close(c.create)
return return
} }

View File

@@ -1,9 +0,0 @@
package dialer
import (
"net"
)
type WireGuardListener interface {
ListenPacketCompat(network, address string) (net.PacketConn, error)
}

View File

@@ -1,11 +0,0 @@
//go:build with_wireguard
package dialer
import (
"github.com/sagernet/wireguard-go/conn"
)
var _ WireGuardListener = (conn.Listener)(nil)
var wgControlFns = conn.ControlFns

View File

@@ -1,9 +0,0 @@
//go:build !with_wireguard
package dialer
import (
"github.com/sagernet/sing/common/control"
)
var wgControlFns []control.Func

View File

@@ -32,7 +32,3 @@ func (r *Reader) Lookup(addr netip.Addr) string {
} }
return "unknown" return "unknown"
} }
func (r *Reader) Close() error {
return r.reader.Close()
}

View File

@@ -1,16 +1,11 @@
package mux package mux
import ( import (
"context"
"net"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-mux" "github.com/sagernet/sing-mux"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger" "github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
) )
@@ -35,7 +30,7 @@ func NewClientWithOptions(dialer N.Dialer, logger logger.Logger, options option.
} }
} }
return mux.NewClient(mux.Options{ return mux.NewClient(mux.Options{
Dialer: &clientDialer{dialer}, Dialer: dialer,
Logger: logger, Logger: logger,
Protocol: options.Protocol, Protocol: options.Protocol,
MaxConnections: options.MaxConnections, MaxConnections: options.MaxConnections,
@@ -45,15 +40,3 @@ func NewClientWithOptions(dialer N.Dialer, logger logger.Logger, options option.
Brutal: brutalOptions, Brutal: brutalOptions,
}) })
} }
type clientDialer struct {
N.Dialer
}
func (d *clientDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
return d.Dialer.DialContext(adapter.OverrideContext(ctx), network, destination)
}
func (d *clientDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
return d.Dialer.ListenPacket(adapter.OverrideContext(ctx), destination)
}

View File

@@ -223,7 +223,7 @@ func getExecPathFromPID(pid uint32) (string, error) {
r1, _, err := syscall.SyscallN( r1, _, err := syscall.SyscallN(
procQueryFullProcessImageNameW.Addr(), procQueryFullProcessImageNameW.Addr(),
uintptr(h), uintptr(h),
uintptr(0), uintptr(1),
uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&buf[0])),
uintptr(unsafe.Pointer(&size)), uintptr(unsafe.Pointer(&size)),
) )

View File

@@ -16,40 +16,30 @@ import (
) )
type LinuxSystemProxy struct { type LinuxSystemProxy struct {
hasGSettings bool hasGSettings bool
kWriteConfigCmd string hasKWriteConfig5 bool
sudoUser string sudoUser string
serverAddr M.Socksaddr serverAddr M.Socksaddr
supportSOCKS bool supportSOCKS bool
isEnabled bool isEnabled bool
} }
func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, supportSOCKS bool) (*LinuxSystemProxy, error) { func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, supportSOCKS bool) (*LinuxSystemProxy, error) {
hasGSettings := common.Error(exec.LookPath("gsettings")) == nil hasGSettings := common.Error(exec.LookPath("gsettings")) == nil
kWriteConfigCmds := []string{ hasKWriteConfig5 := common.Error(exec.LookPath("kwriteconfig5")) == nil
"kwriteconfig5",
"kwriteconfig6",
}
var kWriteConfigCmd string
for _, cmd := range kWriteConfigCmds {
if common.Error(exec.LookPath(cmd)) == nil {
kWriteConfigCmd = cmd
break
}
}
var sudoUser string var sudoUser string
if os.Getuid() == 0 { if os.Getuid() == 0 {
sudoUser = os.Getenv("SUDO_USER") sudoUser = os.Getenv("SUDO_USER")
} }
if !hasGSettings && kWriteConfigCmd == "" { if !hasGSettings && !hasKWriteConfig5 {
return nil, E.New("unsupported desktop environment") return nil, E.New("unsupported desktop environment")
} }
return &LinuxSystemProxy{ return &LinuxSystemProxy{
hasGSettings: hasGSettings, hasGSettings: hasGSettings,
kWriteConfigCmd: kWriteConfigCmd, hasKWriteConfig5: hasKWriteConfig5,
sudoUser: sudoUser, sudoUser: sudoUser,
serverAddr: serverAddr, serverAddr: serverAddr,
supportSOCKS: supportSOCKS, supportSOCKS: supportSOCKS,
}, nil }, nil
} }
@@ -80,8 +70,8 @@ func (p *LinuxSystemProxy) Enable() error {
return err return err
} }
} }
if p.kWriteConfigCmd != "" { if p.hasKWriteConfig5 {
err := p.runAsUser(p.kWriteConfigCmd, "--file", "kioslaverc", "--group", "Proxy Settings", "--key", "ProxyType", "1") err := p.runAsUser("kwriteconfig5", "--file", "kioslaverc", "--group", "Proxy Settings", "--key", "ProxyType", "1")
if err != nil { if err != nil {
return err return err
} }
@@ -93,7 +83,7 @@ func (p *LinuxSystemProxy) Enable() error {
if err != nil { if err != nil {
return err return err
} }
err = p.runAsUser(p.kWriteConfigCmd, "--file", "kioslaverc", "--group", "Proxy Settings", "--key", "Authmode", "0") err = p.runAsUser("kwriteconfig5", "--file", "kioslaverc", "--group", "Proxy Settings", "--key", "Authmode", "0")
if err != nil { if err != nil {
return err return err
} }
@@ -113,8 +103,8 @@ func (p *LinuxSystemProxy) Disable() error {
return err return err
} }
} }
if p.kWriteConfigCmd != "" { if p.hasKWriteConfig5 {
err := p.runAsUser(p.kWriteConfigCmd, "--file", "kioslaverc", "--group", "Proxy Settings", "--key", "ProxyType", "0") err := p.runAsUser("kwriteconfig5", "--file", "kioslaverc", "--group", "Proxy Settings", "--key", "ProxyType", "0")
if err != nil { if err != nil {
return err return err
} }
@@ -160,7 +150,7 @@ func (p *LinuxSystemProxy) setKDEProxy(proxyTypes ...string) error {
proxyUrl = "http://" + p.serverAddr.String() proxyUrl = "http://" + p.serverAddr.String()
} }
err := p.runAsUser( err := p.runAsUser(
p.kWriteConfigCmd, "kwriteconfig5",
"--file", "--file",
"kioslaverc", "kioslaverc",
"--group", "--group",

View File

@@ -253,7 +253,7 @@ func writeDefaultRule(writer io.Writer, rule option.DefaultHeadlessRule) error {
if len(rule.SourceIPCIDR) > 0 { if len(rule.SourceIPCIDR) > 0 {
err = writeRuleItemCIDR(writer, ruleItemSourceIPCIDR, rule.SourceIPCIDR) err = writeRuleItemCIDR(writer, ruleItemSourceIPCIDR, rule.SourceIPCIDR)
if err != nil { if err != nil {
return E.Cause(err, "source_ip_cidr") return E.Cause(err, "source_ipcidr")
} }
} }
if len(rule.IPCIDR) > 0 { if len(rule.IPCIDR) > 0 {

View File

@@ -105,16 +105,5 @@ func startACME(ctx context.Context, options option.InboundACMEOptions) (*tls.Con
}, },
}) })
config = certmagic.New(cache, *config) config = certmagic.New(cache, *config)
var tlsConfig *tls.Config return config.TLSConfig(), &acmeWrapper{ctx: ctx, cfg: config, cache: cache, domain: options.Domain}, nil
if acmeConfig.DisableTLSALPNChallenge || acmeConfig.DNS01Solver != nil {
tlsConfig = &tls.Config{
GetCertificate: config.GetCertificate,
}
} else {
tlsConfig = &tls.Config{
GetCertificate: config.GetCertificate,
NextProtos: []string{ACMETLS1Protocol},
}
}
return tlsConfig, &acmeWrapper{ctx: ctx, cfg: config, cache: cache, domain: options.Domain}, nil
} }

View File

@@ -1,3 +0,0 @@
package tls
const ACMETLS1Protocol = "acme-tls/1"

View File

@@ -27,10 +27,11 @@ func (c *echClientConfig) DialEarly(ctx context.Context, conn net.PacketConn, ad
return quic.DialEarly(ctx, conn, addr, c.config, config) return quic.DialEarly(ctx, conn, addr, c.config, config)
} }
func (c *echClientConfig) CreateTransport(conn net.PacketConn, quicConnPtr *quic.EarlyConnection, serverAddr M.Socksaddr, quicConfig *quic.Config) http.RoundTripper { func (c *echClientConfig) CreateTransport(conn net.PacketConn, quicConnPtr *quic.EarlyConnection, serverAddr M.Socksaddr, quicConfig *quic.Config, enableDatagrams bool) http.RoundTripper {
return &http3.RoundTripper{ return &http3.RoundTripper{
TLSClientConfig: c.config, TLSClientConfig: c.config,
QUICConfig: quicConfig, QuicConfig: quicConfig,
EnableDatagrams: enableDatagrams,
Dial: func(ctx context.Context, addr string, tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlyConnection, error) { Dial: func(ctx context.Context, addr string, tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlyConnection, error) {
quicConn, err := quic.DialEarly(ctx, conn, serverAddr.UDPAddr(), tlsCfg, cfg) quicConn, err := quic.DialEarly(ctx, conn, serverAddr.UDPAddr(), tlsCfg, cfg)
if err != nil { if err != nil {

View File

@@ -39,19 +39,11 @@ func (c *STDServerConfig) SetServerName(serverName string) {
} }
func (c *STDServerConfig) NextProtos() []string { func (c *STDServerConfig) NextProtos() []string {
if c.acmeService != nil && len(c.config.NextProtos) > 1 && c.config.NextProtos[0] == ACMETLS1Protocol { return c.config.NextProtos
return c.config.NextProtos[1:]
} else {
return c.config.NextProtos
}
} }
func (c *STDServerConfig) SetNextProtos(nextProto []string) { func (c *STDServerConfig) SetNextProtos(nextProto []string) {
if c.acmeService != nil && len(c.config.NextProtos) > 1 && c.config.NextProtos[0] == ACMETLS1Protocol { c.config.NextProtos = nextProto
c.config.NextProtos = append(c.config.NextProtos[:1], nextProto...)
} else {
c.config.NextProtos = nextProto
}
} }
func (c *STDServerConfig) Config() (*STDConfig, error) { func (c *STDServerConfig) Config() (*STDConfig, error) {

View File

@@ -1,5 +0,0 @@
//go:build with_quic
package constant
const WithQUIC = true

View File

@@ -1,5 +0,0 @@
//go:build !with_quic
package constant
const WithQUIC = false

View File

@@ -3,18 +3,15 @@ package constant
import "time" import "time"
const ( const (
TCPKeepAliveInitial = 10 * time.Minute TCPTimeout = 5 * time.Second
TCPKeepAliveInterval = 75 * time.Second ReadPayloadTimeout = 300 * time.Millisecond
TCPTimeout = 5 * time.Second DNSTimeout = 10 * time.Second
ReadPayloadTimeout = 300 * time.Millisecond QUICTimeout = 30 * time.Second
DNSTimeout = 10 * time.Second STUNTimeout = 15 * time.Second
QUICTimeout = 30 * time.Second UDPTimeout = 5 * time.Minute
STUNTimeout = 15 * time.Second DefaultURLTestInterval = 3 * time.Minute
UDPTimeout = 5 * time.Minute DefaultURLTestIdleTimeout = 30 * time.Minute
DefaultURLTestInterval = 3 * time.Minute DefaultStartTimeout = 10 * time.Second
DefaultURLTestIdleTimeout = 30 * time.Minute DefaultStopTimeout = 5 * time.Second
StartTimeout = 10 * time.Second DefaultStopFatalTimeout = 10 * time.Second
StopTimeout = 5 * time.Second
FatalStopTimeout = 10 * time.Second
FakeIPMetadataSaveInterval = 10 * time.Second
) )

View File

@@ -5,7 +5,6 @@ import (
"net/http/pprof" "net/http/pprof"
"runtime" "runtime"
"runtime/debug" "runtime/debug"
"strings"
"github.com/sagernet/sing-box/common/humanize" "github.com/sagernet/sing-box/common/humanize"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
@@ -48,20 +47,12 @@ func applyDebugListenOption(options option.DebugOptions) {
encoder.SetIndent("", " ") encoder.SetIndent("", " ")
encoder.Encode(memObject) encoder.Encode(memObject)
}) })
r.Route("/pprof", func(r chi.Router) { r.HandleFunc("/pprof", pprof.Index)
r.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { r.HandleFunc("/pprof/*", pprof.Index)
if !strings.HasSuffix(request.URL.Path, "/") { r.HandleFunc("/pprof/cmdline", pprof.Cmdline)
http.Redirect(writer, request, request.URL.Path+"/", http.StatusMovedPermanently) r.HandleFunc("/pprof/profile", pprof.Profile)
} else { r.HandleFunc("/pprof/symbol", pprof.Symbol)
pprof.Index(writer, request) r.HandleFunc("/pprof/trace", pprof.Trace)
}
})
r.HandleFunc("/*", pprof.Index)
r.HandleFunc("/cmdline", pprof.Cmdline)
r.HandleFunc("/profile", pprof.Profile)
r.HandleFunc("/symbol", pprof.Symbol)
r.HandleFunc("/trace", pprof.Trace)
})
}) })
debugHTTPServer = &http.Server{ debugHTTPServer = &http.Server{
Addr: options.Listen, Addr: options.Listen,

View File

@@ -1,5 +1,3 @@
//go:build linux || darwin
package box package box
import ( import (

View File

@@ -1,4 +1,4 @@
//go:build !(linux || darwin) //go:build !linux
package box package box

View File

@@ -2,444 +2,9 @@
icon: material/alert-decagram icon: material/alert-decagram
--- ---
### 1.9.2 #### 1.8.0-beta.2
* Fixes and improvements
### 1.9.1
* Fixes and improvements
### 1.9.0
* Fixes and improvements
Important changes since 1.8:
* `domain_suffix` behavior update **1**
* `process_path` format update on Windows **2**
* Add address filter DNS rule items **3**
* Add support for `client-subnet` DNS options **4**
* Add rejected DNS response cache support **5**
* Add `bypass_domain` and `search_domain` platform HTTP proxy options **6**
* Fix missing `rule_set_ipcidr_match_source` item in DNS rules **7**
* Handle Windows power events
* Always disable cache for fake-ip DNS transport if `dns.independent_cache` disabled
* Improve DNS truncate behavior
* Update Hysteria protocol
* Update quic-go to v0.43.1
* Update gVisor to 20240422.0
* Mitigating TunnelVision attacks **8**
**1**:
See [Migration](/migration/#domain_suffix-behavior-update).
**2**:
See [Migration](/migration/#process_path-format-update-on-windows).
**3**:
The new DNS feature allows you to more precisely bypass Chinese websites via **DNS leaks**. Do not use plain local DNS
if using this method.
See [Address Filter Fields](/configuration/dns/rule#address-filter-fields).
[Client example](/manual/proxy/client#traffic-bypass-usage-for-chinese-users) updated.
**4**:
See [DNS](/configuration/dns), [DNS Server](/configuration/dns/server) and [DNS Rules](/configuration/dns/rule).
Since this feature makes the scenario mentioned in `alpha.1` no longer leak DNS requests,
the [Client example](/manual/proxy/client#traffic-bypass-usage-for-chinese-users) has been updated.
**5**:
The new feature allows you to cache the check results of
[Address filter DNS rule items](/configuration/dns/rule/#address-filter-fields) until expiration.
**6**:
See [TUN](/configuration/inbound/tun) inbound.
**7**:
See [DNS Rule](/configuration/dns/rule/).
**8**:
See [TunnelVision](/manual/misc/tunnelvision).
#### 1.9.0-rc.22
* Fixes and improvements
#### 1.9.0-rc.20
* Prioritize `*_route_address` in linux auto-route
* Fix `*_route_address` in darwin auto-route
#### 1.8.14
* Fix hysteria2 panic
* Fixes and improvements
#### 1.9.0-rc.18
* Add custom prefix support in EDNS0 client subnet options
* Fix hysteria2 crash
* Fix `store_rdrc` corrupted
* Update quic-go to v0.43.1
* Fixes and improvements
#### 1.9.0-rc.16
* Mitigating TunnelVision attacks **1**
* Fixes and improvements
**1**:
See [TunnelVision](/manual/misc/tunnelvision).
#### 1.9.0-rc.15
* Fixes and improvements
#### 1.8.13
* Fix fake-ip mapping
* Fixes and improvements
#### 1.9.0-rc.14
* Fixes and improvements
#### 1.9.0-rc.13
* Update Hysteria protocol
* Update quic-go to v0.43.0
* Update gVisor to 20240422.0
* Fixes and improvements
#### 1.8.12
* Now we have official APT and DNF repositories **1**
* Fix packet MTU for QUIC protocols
* Fixes and improvements
**1**:
Including stable and beta versions, see https://sing-box.sagernet.org/installation/package-manager/
#### 1.9.0-rc.11
* Fixes and improvements
#### 1.8.11
* Fixes and improvements
#### 1.8.10
* Fixes and improvements
#### 1.9.0-beta.17
* Update `quic-go` to v0.42.0
* Fixes and improvements
#### 1.9.0-beta.16
* Fixes and improvements
_Our Testflight distribution has been temporarily blocked by Apple (possibly due to too many beta versions)
and you cannot join the test, install or update the sing-box beta app right now.
Please wait patiently for processing._
#### 1.9.0-beta.14
* Update gVisor to 20240212.0-65-g71212d503
* Fixes and improvements
#### 1.8.9
* Fixes and improvements
#### 1.8.8
* Fixes and improvements
#### 1.9.0-beta.7
* Fixes and improvements
#### 1.9.0-beta.6
* Fix address filter DNS rule items **1**
* Fix DNS outbound responding with wrong data
* Fixes and improvements
**1**:
Fixed an issue where address filter DNS rule was incorrectly rejected under certain circumstances.
If you have enabled `store_rdrc` to save results, consider clearing the cache file.
#### 1.8.7
* Fixes and improvements
#### 1.9.0-alpha.15
* Fixes and improvements
#### 1.9.0-alpha.14
* Improve DNS truncate behavior
* Fixes and improvements
#### 1.9.0-alpha.13
* Fixes and improvements
#### 1.8.6
* Fixes and improvements
#### 1.9.0-alpha.12
* Handle Windows power events
* Always disable cache for fake-ip DNS transport if `dns.independent_cache` disabled
* Fixes and improvements
#### 1.9.0-alpha.11
* Fix missing `rule_set_ipcidr_match_source` item in DNS rules **1**
* Fixes and improvements
**1**:
See [DNS Rule](/configuration/dns/rule/).
#### 1.9.0-alpha.10
* Add `bypass_domain` and `search_domain` platform HTTP proxy options **1**
* Fixes and improvements
**1**:
See [TUN](/configuration/inbound/tun) inbound.
#### 1.9.0-alpha.8
* Add rejected DNS response cache support **1**
* Fixes and improvements
**1**:
The new feature allows you to cache the check results of
[Address filter DNS rule items](/configuration/dns/rule/#address-filter-fields) until expiration.
#### 1.9.0-alpha.7
* Update gVisor to 20240206.0
* Fixes and improvements
#### 1.9.0-alpha.6
* Fixes and improvements
#### 1.9.0-alpha.3
* Update `quic-go` to v0.41.0
* Fixes and improvements
#### 1.9.0-alpha.2
* Add support for `client-subnet` DNS options **1**
* Fixes and improvements
**1**:
See [DNS](/configuration/dns), [DNS Server](/configuration/dns/server) and [DNS Rules](/configuration/dns/rule).
Since this feature makes the scenario mentioned in `alpha.1` no longer leak DNS requests,
the [Client example](/manual/proxy/client#traffic-bypass-usage-for-chinese-users) has been updated.
#### 1.9.0-alpha.1
* `domain_suffix` behavior update **1**
* `process_path` format update on Windows **2**
* Add address filter DNS rule items **3**
**1**:
See [Migration](/migration/#domain_suffix-behavior-update).
**2**:
See [Migration](/migration/#process_path-format-update-on-windows).
**3**:
The new DNS feature allows you to more precisely bypass Chinese websites via **DNS leaks**. Do not use plain local DNS
if using this method.
See [Address Filter Fields](/configuration/dns/rule#address-filter-fields).
[Client example](/manual/proxy/client#traffic-bypass-usage-for-chinese-users) updated.
#### 1.8.5
* Fixes and improvements
#### 1.8.4
* Fixes and improvements
#### 1.8.2
* Fixes and improvements
#### 1.8.1
* Fixes and improvements
### 1.8.0
* Fixes and improvements
Important changes since 1.7:
* Migrate cache file from Clash API to independent options **1**
* Introducing [Rule Set](/configuration/rule-set/) **2**
* Add `sing-box geoip`, `sing-box geosite` and `sing-box rule-set` commands **3**
* Allow nested logical rules **4**
* Independent `source_ip_is_private` and `ip_is_private` rules **5**
* Add context to JSON decode error message **6**
* Reject internal fake-ip queries **7**
* Add GSO support for TUN and WireGuard system interface **8**
* Add `idle_timeout` for URLTest outbound **9**
* Add simple loopback detect
* Optimize memory usage of idle connections
* Update uTLS to 1.5.4 **10**
* Update dependencies **11**
**1**:
See [Cache File](/configuration/experimental/cache-file/) and
[Migration](/migration/#migrate-cache-file-from-clash-api-to-independent-options).
**2**:
Rule set is independent collections of rules that can be compiled into binaries to improve performance.
Compared to legacy GeoIP and Geosite resources,
it can include more types of rules, load faster,
use less memory, and update automatically.
See [Route#rule_set](/configuration/route/#rule_set),
[Route Rule](/configuration/route/rule/),
[DNS Rule](/configuration/dns/rule/),
[Rule Set](/configuration/rule-set/),
[Source Format](/configuration/rule-set/source-format/) and
[Headless Rule](/configuration/rule-set/headless-rule/).
For GEO resources migration, see [Migrate GeoIP to rule sets](/migration/#migrate-geoip-to-rule-sets) and
[Migrate Geosite to rule sets](/migration/#migrate-geosite-to-rule-sets).
**3**:
New commands manage GeoIP, Geosite and rule set resources, and help you migrate GEO resources to rule sets.
**4**:
Logical rules in route rules, DNS rules, and the new headless rule now allow nesting of logical rules.
**5**:
The `private` GeoIP country never existed and was actually implemented inside V2Ray.
Since GeoIP was deprecated, we made this rule independent, see [Migration](/migration/#migrate-geoip-to-rule-sets).
**6**:
JSON parse errors will now include the current key path.
Only takes effect when compiled with Go 1.21+.
**7**:
All internal DNS queries now skip DNS rules with `server` type `fakeip`,
and the default DNS server can no longer be `fakeip`.
This change is intended to break incorrect usage and essentially requires no action.
**8**:
See [TUN](/configuration/inbound/tun/) inbound and [WireGuard](/configuration/outbound/wireguard/) outbound.
**9**:
When URLTest is idle for a certain period of time, the scheduled delay test will be paused.
**10**:
Added some new [fingerprints](/configuration/shared/tls#utls).
Also, starting with this release, uTLS requires at least Go 1.20.
**11**:
Updated `cloudflare-tls`, `gomobile`, `smux`, `tfo-go` and `wireguard-go` to latest, `quic-go` to `0.40.1` and `gvisor`
to `20231204.0`
#### 1.8.0-rc.11
* Fixes and improvements
#### 1.7.8
* Fixes and improvements
#### 1.8.0-rc.10
* Fixes and improvements
#### 1.7.7
* Fix V2Ray transport `path` validation behavior **1**
* Fixes and improvements
**1**:
See [V2Ray transport](/configuration/shared/v2ray-transport/).
#### 1.8.0-rc.7
* Fixes and improvements
#### 1.8.0-rc.3
* Fix V2Ray transport `path` validation behavior **1**
* Fixes and improvements
**1**:
See [V2Ray transport](/configuration/shared/v2ray-transport/).
#### 1.7.6
* Fixes and improvements
#### 1.8.0-rc.1
* Fixes and improvements
#### 1.8.0-beta.9
* Add simple loopback detect
* Fixes and improvements
#### 1.7.5
* Fix GSO support
* Fixes and improvements * Fixes and improvements
#### 1.8.0-alpha.17 #### 1.8.0-alpha.17
@@ -451,7 +16,7 @@ See [V2Ray transport](/configuration/shared/v2ray-transport/).
**1**: **1**:
See [TUN](/configuration/inbound/tun/) inbound and [WireGuard](/configuration/outbound/wireguard/) outbound. See [TUN](/configuration/inbound/tun) inbound and [WireGuard](/configuration/outbound/wireguard) outbound.
**2**: **2**:
@@ -464,6 +29,10 @@ Updated `cloudflare-tls`, `gomobile`, `smux`, `tfo-go` and `wireguard-go` to lat
This may break something, good luck! This may break something, good luck!
#### 1.7.5
* Fixes and improvements
#### 1.7.4 #### 1.7.4
* Fixes and improvements * Fixes and improvements
@@ -563,13 +132,13 @@ Since GeoIP was deprecated, we made this rule independent, see [Migration](/migr
#### 1.8.0-alpha.1 #### 1.8.0-alpha.1
* Migrate cache file from Clash API to independent options **1** * Migrate cache file from Clash API to independent options **1**
* Introducing [Rule Set](/configuration/rule-set/) **2** * Introducing [Rule Set](/configuration/rule-set) **2**
* Add `sing-box geoip`, `sing-box geosite` and `sing-box rule-set` commands **3** * Add `sing-box geoip`, `sing-box geosite` and `sing-box rule-set` commands **3**
* Allow nested logical rules **4** * Allow nested logical rules **4**
**1**: **1**:
See [Cache File](/configuration/experimental/cache-file/) and See [Cache File](/configuration/experimental/cache-file) and
[Migration](/migration/#migrate-cache-file-from-clash-api-to-independent-options). [Migration](/migration/#migrate-cache-file-from-clash-api-to-independent-options).
**2**: **2**:
@@ -580,11 +149,11 @@ it can include more types of rules, load faster,
use less memory, and update automatically. use less memory, and update automatically.
See [Route#rule_set](/configuration/route/#rule_set), See [Route#rule_set](/configuration/route/#rule_set),
[Route Rule](/configuration/route/rule/), [Route Rule](/configuration/route/rule),
[DNS Rule](/configuration/dns/rule/), [DNS Rule](/configuration/dns/rule),
[Rule Set](/configuration/rule-set/), [Rule Set](/configuration/rule-set),
[Source Format](/configuration/rule-set/source-format/) and [Source Format](/configuration/rule-set/source-format) and
[Headless Rule](/configuration/rule-set/headless-rule/). [Headless Rule](/configuration/rule-set/headless-rule).
For GEO resources migration, see [Migrate GeoIP to rule sets](/migration/#migrate-geoip-to-rule-sets) and For GEO resources migration, see [Migrate GeoIP to rule sets](/migration/#migrate-geoip-to-rule-sets) and
[Migrate Geosite to rule sets](/migration/#migrate-geosite-to-rule-sets). [Migrate Geosite to rule sets](/migration/#migrate-geosite-to-rule-sets).
@@ -597,14 +166,14 @@ New commands manage GeoIP, Geosite and rule set resources, and help you migrate
Logical rules in route rules, DNS rules, and the new headless rule now allow nesting of logical rules. Logical rules in route rules, DNS rules, and the new headless rule now allow nesting of logical rules.
### 1.7.0 #### 1.7.0
* Fixes and improvements * Fixes and improvements
Important changes since 1.6: Important changes since 1.6:
* Add [exclude route support](/configuration/inbound/tun/) for TUN inbound * Add [exclude route support](/configuration/inbound/tun) for TUN inbound
* Add `udp_disable_domain_unmapping` [inbound listen option](/configuration/shared/listen/) **1** * Add `udp_disable_domain_unmapping` [inbound listen option](/configuration/shared/listen) **1**
* Add [HTTPUpgrade V2Ray transport](/configuration/shared/v2ray-transport#HTTPUpgrade) support **2** * Add [HTTPUpgrade V2Ray transport](/configuration/shared/v2ray-transport#HTTPUpgrade) support **2**
* Migrate multiplex and UoT server to inbound **3** * Migrate multiplex and UoT server to inbound **3**
* Add TCP Brutal support for multiplex **4** * Add TCP Brutal support for multiplex **4**
@@ -635,11 +204,11 @@ options.
**4** **4**
Hysteria Brutal Congestion Control Algorithm in TCP. A kernel module needs to be installed on the Linux server, Hysteria Brutal Congestion Control Algorithm in TCP. A kernel module needs to be installed on the Linux server,
see [TCP Brutal](/configuration/shared/tcp-brutal/) for details. see [TCP Brutal](/configuration/shared/tcp-brutal) for details.
**5**: **5**:
Only supported in graphical clients on Android and Apple platforms. Only supported in graphical clients on Android and iOS.
#### 1.7.0-rc.3 #### 1.7.0-rc.3
@@ -676,7 +245,7 @@ Only supported in graphical clients on Android and Apple platforms.
**1**: **1**:
Only supported in graphical clients on Android and Apple platforms. Only supported in graphical clients on Android and iOS.
#### 1.7.0-beta.3 #### 1.7.0-beta.3
@@ -724,7 +293,7 @@ Only supported in graphical clients on Android and Apple platforms.
#### 1.6.1 #### 1.6.1
* Our [Android client](/installation/clients/sfa/) is now available in the Google Play Store ▶️ * Our [Android client](/installation/clients/sfa) is now available in the Google Play Store ▶️
* Fixes and improvements * Fixes and improvements
#### 1.7.0-alpha.6 #### 1.7.0-alpha.6
@@ -744,7 +313,7 @@ options.
**2** **2**
Hysteria Brutal Congestion Control Algorithm in TCP. A kernel module needs to be installed on the Linux server, Hysteria Brutal Congestion Control Algorithm in TCP. A kernel module needs to be installed on the Linux server,
see [TCP Brutal](/configuration/shared/tcp-brutal/) for details. see [TCP Brutal](/configuration/shared/tcp-brutal) for details.
#### 1.7.0-alpha.3 #### 1.7.0-alpha.3
@@ -757,19 +326,19 @@ Introduced in V2Ray 5.10.0.
The new HTTPUpgrade transport has better performance than WebSocket and is better suited for CDN abuse. The new HTTPUpgrade transport has better performance than WebSocket and is better suited for CDN abuse.
### 1.6.0 #### 1.6.0
* Fixes and improvements * Fixes and improvements
Important changes since 1.5: Important changes since 1.5:
* Our [Apple tvOS client](/installation/clients/sft/) is now available in the App Store 🍎 * Our [Apple tvOS client](/installation/clients/sft) is now available in the App Store 🍎
* Update BBR congestion control for TUIC and Hysteria2 **1** * Update BBR congestion control for TUIC and Hysteria2 **1**
* Update brutal congestion control for Hysteria2 * Update brutal congestion control for Hysteria2
* Add `brutal_debug` option for Hysteria2 * Add `brutal_debug` option for Hysteria2
* Update legacy Hysteria protocol **2** * Update legacy Hysteria protocol **2**
* Add TLS self sign key pair generate command * Add TLS self sign key pair generate command
* Remove [Deprecated Features](/deprecated/) by agreement * Remove [Deprecated Features](/deprecated) by agreement
**1**: **1**:
@@ -787,8 +356,8 @@ the old protocol (Hysteria 1) have been updated to be consistent with Hysteria 2
#### 1.7.0-alpha.1 #### 1.7.0-alpha.1
* Add [exclude route support](/configuration/inbound/tun/) for TUN inbound * Add [exclude route support](/configuration/inbound/tun) for TUN inbound
* Add `udp_disable_domain_unmapping` [inbound listen option](/configuration/shared/listen/) **1** * Add `udp_disable_domain_unmapping` [inbound listen option](/configuration/shared/listen) **1**
* Fixes and improvements * Fixes and improvements
**1**: **1**:
@@ -908,7 +477,7 @@ introduce new issues.
#### 1.5.2 #### 1.5.2
* Our [Apple tvOS client](/installation/clients/sft/) is now available in the App Store 🍎 * Our [Apple tvOS client](/installation/clients/sft) is now available in the App Store 🍎
* Fixes and improvements * Fixes and improvements
#### 1.6.0-alpha.3 #### 1.6.0-alpha.3
@@ -928,7 +497,7 @@ introduce new issues.
* Update BBR congestion control for TUIC and Hysteria2 **1** * Update BBR congestion control for TUIC and Hysteria2 **1**
* Update quic-go to v0.39.0 * Update quic-go to v0.39.0
* Update gVisor to 20230814.0 * Update gVisor to 20230814.0
* Remove [Deprecated Features](/deprecated/) by agreement * Remove [Deprecated Features](/deprecated) by agreement
* Fixes and improvements * Fixes and improvements
**1**: **1**:
@@ -936,13 +505,13 @@ introduce new issues.
None of the existing Golang BBR congestion control implementations have been reviewed or unit tested. None of the existing Golang BBR congestion control implementations have been reviewed or unit tested.
This update is intended to address the multi-send defects of the old implementation and may introduce new issues. This update is intended to address the multi-send defects of the old implementation and may introduce new issues.
### 1.5.0 #### 1.5.0
* Fixes and improvements * Fixes and improvements
Important changes since 1.4: Important changes since 1.4:
* Add TLS [ECH server](/configuration/shared/tls/) support * Add TLS [ECH server](/configuration/shared/tls) support
* Improve TLS TCH client configuration * Improve TLS TCH client configuration
* Add TLS ECH key pair generator **1** * Add TLS ECH key pair generator **1**
* Add TLS ECH support for QUIC based protocols **2** * Add TLS ECH support for QUIC based protocols **2**
@@ -951,7 +520,7 @@ Important changes since 1.4:
* Add `interrupt_exist_connections` option for `Selector` and `URLTest` outbounds **4** * Add `interrupt_exist_connections` option for `Selector` and `URLTest` outbounds **4**
* Add DNS01 challenge support for ACME TLS certificate issuer **5** * Add DNS01 challenge support for ACME TLS certificate issuer **5**
* Add `merge` command **6** * Add `merge` command **6**
* Mark [Deprecated Features](/deprecated/) * Mark [Deprecated Features](/deprecated)
**1**: **1**:
@@ -963,7 +532,7 @@ All inbounds and outbounds are supported, including `Naiveproxy`, `Hysteria[/2]`
**3**: **3**:
See [Hysteria2 inbound](/configuration/inbound/hysteria2/) and [Hysteria2 outbound](/configuration/outbound/hysteria2/) See [Hysteria2 inbound](/configuration/inbound/hysteria2) and [Hysteria2 outbound](/configuration/outbound/hysteria2)
For protocol description, please refer to [https://v2.hysteria.network](https://v2.hysteria.network) For protocol description, please refer to [https://v2.hysteria.network](https://v2.hysteria.network)
@@ -976,7 +545,7 @@ Only inbound connections are affected by this setting, internal connections will
**5**: **5**:
Only `Alibaba Cloud DNS` and `Cloudflare` are supported, see [ACME Fields](/configuration/shared/tls#acme-fields) Only `Alibaba Cloud DNS` and `Cloudflare` are supported, see [ACME Fields](/configuration/shared/tls#acme-fields)
and [DNS01 Challenge Fields](/configuration/shared/dns01_challenge/). and [DNS01 Challenge Fields](/configuration/shared/dns01_challenge).
**6**: **6**:
@@ -1058,7 +627,7 @@ Global Flags:
Only `Alibaba Cloud DNS` and `Cloudflare` are supported, Only `Alibaba Cloud DNS` and `Cloudflare` are supported,
see [ACME Fields](/configuration/shared/tls#acme-fields) see [ACME Fields](/configuration/shared/tls#acme-fields)
and [DNS01 Challenge Fields](/configuration/shared/dns01_challenge/). and [DNS01 Challenge Fields](/configuration/shared/dns01_challenge).
#### 1.5.0-beta.10 #### 1.5.0-beta.10
@@ -1087,7 +656,7 @@ Only inbound connections are affected by this setting, internal connections will
* Fix compatibility issues with official Hysteria2 server and client * Fix compatibility issues with official Hysteria2 server and client
* Fixes and improvements * Fixes and improvements
* Mark [deprecated features](/deprecated/) * Mark [deprecated features](/deprecated)
#### 1.5.0-beta.3 #### 1.5.0-beta.3
@@ -1106,13 +675,13 @@ Hysteria2 server and client when using `fastOpen=false` or UDP MTU >= 1200.
**1**: **1**:
See [Hysteria2 inbound](/configuration/inbound/hysteria2/) and [Hysteria2 outbound](/configuration/outbound/hysteria2/) See [Hysteria2 inbound](/configuration/inbound/hysteria2) and [Hysteria2 outbound](/configuration/outbound/hysteria2)
For protocol description, please refer to [https://v2.hysteria.network](https://v2.hysteria.network) For protocol description, please refer to [https://v2.hysteria.network](https://v2.hysteria.network)
#### 1.5.0-beta.1 #### 1.5.0-beta.1
* Add TLS [ECH server](/configuration/shared/tls/) support * Add TLS [ECH server](/configuration/shared/tls) support
* Improve TLS TCH client configuration * Improve TLS TCH client configuration
* Add TLS ECH key pair generator **1** * Add TLS ECH key pair generator **1**
* Add TLS ECH support for QUIC based protocols **2** * Add TLS ECH support for QUIC based protocols **2**
@@ -1130,7 +699,7 @@ All inbounds and outbounds are supported, including `Naiveproxy`, `Hysteria`, `T
* Fixes and improvements * Fixes and improvements
### 1.4.0 #### 1.4.0
* Fix bugs and update dependencies * Fix bugs and update dependencies
@@ -1145,12 +714,12 @@ Important changes since 1.3:
*1*: *1*:
See [TUIC inbound](/configuration/inbound/tuic/) See [TUIC inbound](/configuration/inbound/tuic)
and [TUIC outbound](/configuration/outbound/tuic/) and [TUIC outbound](/configuration/outbound/tuic)
**2**: **2**:
This is the TUIC port of the [UDP over TCP protocol](/configuration/shared/udp-over-tcp/), designed to provide a QUIC This is the TUIC port of the [UDP over TCP protocol](/configuration/shared/udp-over-tcp), designed to provide a QUIC
stream based UDP relay mode that TUIC does not provide. Since it is an add-on protocol, you will need to use sing-box or stream based UDP relay mode that TUIC does not provide. Since it is an add-on protocol, you will need to use sing-box or
another program compatible with the protocol as a server. another program compatible with the protocol as a server.
@@ -1181,7 +750,7 @@ Requires sing-box to be compiled with Go 1.21.
**1**: **1**:
This is the TUIC port of the [UDP over TCP protocol](/configuration/shared/udp-over-tcp/), designed to provide a QUIC This is the TUIC port of the [UDP over TCP protocol](/configuration/shared/udp-over-tcp), designed to provide a QUIC
stream based UDP relay mode that TUIC does not provide. Since it is an add-on protocol, you will need to use sing-box or stream based UDP relay mode that TUIC does not provide. Since it is an add-on protocol, you will need to use sing-box or
another program compatible with the protocol as a server. another program compatible with the protocol as a server.
@@ -1219,8 +788,8 @@ Requires sing-box to be compiled with Go 1.21.
*1*: *1*:
See [TUIC inbound](/configuration/inbound/tuic/) See [TUIC inbound](/configuration/inbound/tuic)
and [TUIC outbound](/configuration/outbound/tuic/) and [TUIC outbound](/configuration/outbound/tuic)
#### 1.3.6 #### 1.3.6
@@ -1229,7 +798,7 @@ and [TUIC outbound](/configuration/outbound/tuic/)
#### 1.3.5 #### 1.3.5
* Fixes and improvements * Fixes and improvements
* Introducing our [Apple tvOS](/installation/clients/sft/) client applications **1** * Introducing our [Apple tvOS](/installation/clients/sft) client applications **1**
* Add per app proxy and app installed/updated trigger support for Android client * Add per app proxy and app installed/updated trigger support for Android client
* Add profile sharing support for Android/iOS/macOS clients * Add profile sharing support for Android/iOS/macOS clients
@@ -1256,8 +825,7 @@ downloaded through TestFlight.
#### 1.3.1-beta.3 #### 1.3.1-beta.3
* Introducing our [new iOS](/installation/clients/sfi/) and [macOS](/installation/clients/sfm/) client applications **1 * Introducing our [new iOS](/installation/clients/sfi) and [macOS](/installation/clients/sfm) client applications **1**
**
* Fixes and improvements * Fixes and improvements
**1**: **1**:
@@ -1272,13 +840,13 @@ The old testflight link and app are no longer valid.
* Fixes and improvements * Fixes and improvements
### 1.3.0 #### 1.3.0
* Fix bugs and update dependencies * Fix bugs and update dependencies
Important changes since 1.2: Important changes since 1.2:
* Add [FakeIP](/configuration/dns/fakeip/) support **1** * Add [FakeIP](/configuration/dns/fakeip) support **1**
* Improve multiplex **2** * Improve multiplex **2**
* Add [DNS reverse mapping](/configuration/dns#reverse_mapping) support * Add [DNS reverse mapping](/configuration/dns#reverse_mapping) support
* Add `rewrite_ttl` DNS rule action * Add `rewrite_ttl` DNS rule action
@@ -1305,11 +873,11 @@ Important changes since 1.2:
*1*: *1*:
See [FAQ](/faq/fakeip/) for more information. See [FAQ](/faq/fakeip) for more information.
*2*: *2*:
Added new `h2mux` multiplex protocol and `padding` multiplex option, see [Multiplex](/configuration/shared/multiplex/). Added new `h2mux` multiplex protocol and `padding` multiplex option, see [Multiplex](/configuration/shared/multiplex).
#### 1.3-rc2 #### 1.3-rc2
@@ -1371,7 +939,7 @@ Improved performance and reduced memory usage.
*1*: *1*:
Added new `h2mux` multiplex protocol and `padding` multiplex option, see [Multiplex](/configuration/shared/multiplex/). Added new `h2mux` multiplex protocol and `padding` multiplex option, see [Multiplex](/configuration/shared/multiplex).
#### 1.2.6 #### 1.2.6
@@ -1423,25 +991,25 @@ This is an incompatible update for XUDP in VLESS if vision flow is enabled.
#### 1.3-beta1 #### 1.3-beta1
* Add [DNS reverse mapping](/configuration/dns#reverse_mapping) support * Add [DNS reverse mapping](/configuration/dns#reverse_mapping) support
* Add [L3 routing](/configuration/route/ip-rule/) support **1** * Add [L3 routing](/configuration/route/ip-rule) support **1**
* Add `rewrite_ttl` DNS rule action * Add `rewrite_ttl` DNS rule action
* Add [FakeIP](/configuration/dns/fakeip/) support **2** * Add [FakeIP](/configuration/dns/fakeip) support **2**
* Add `store_fakeip` Clash API option * Add `store_fakeip` Clash API option
* Add multi-peer support for [WireGuard](/configuration/outbound/wireguard#peers) outbound * Add multi-peer support for [WireGuard](/configuration/outbound/wireguard#peers) outbound
* Add loopback detect * Add loopback detect
*1*: *1*:
It can currently be used to [route connections directly to WireGuard](/examples/wireguard-direct/) or block connections It can currently be used to [route connections directly to WireGuard](/examples/wireguard-direct) or block connections
at the IP layer. at the IP layer.
*2*: *2*:
See [FAQ](/faq/fakeip/) for more information. See [FAQ](/faq/fakeip) for more information.
#### 1.2.3 #### 1.2.3
* Introducing our [new Android client application](/installation/clients/sfa/) * Introducing our [new Android client application](/installation/clients/sfa)
* Improve UDP domain destination NAT * Improve UDP domain destination NAT
* Update reality protocol * Update reality protocol
* Fix TTL calculation for DNS response * Fix TTL calculation for DNS response
@@ -1464,22 +1032,22 @@ to `domain` rule.
* Flush DNS cache for macOS when tun start/close * Flush DNS cache for macOS when tun start/close
* Fix tun's DNS hijacking compatibility with systemd-resolved * Fix tun's DNS hijacking compatibility with systemd-resolved
### 1.2.0 #### 1.2.0
* Fix bugs and update dependencies * Fix bugs and update dependencies
Important changes since 1.1: Important changes since 1.1:
* Introducing our [new iOS client application](/installation/clients/sfi/) * Introducing our [new iOS client application](/installation/clients/sfi)
* Introducing [UDP over TCP protocol version 2](/configuration/shared/udp-over-tcp/) * Introducing [UDP over TCP protocol version 2](/configuration/shared/udp-over-tcp)
* Add [platform options](/configuration/inbound/tun#platform) for tun inbound * Add [platform options](/configuration/inbound/tun#platform) for tun inbound
* Add [ShadowTLS protocol v3](https://github.com/ihciah/shadow-tls/blob/master/docs/protocol-v3-en.md) * Add [ShadowTLS protocol v3](https://github.com/ihciah/shadow-tls/blob/master/docs/protocol-v3-en.md)
* Add [VLESS server](/configuration/inbound/vless/) and [vision](/configuration/outbound/vless#flow) support * Add [VLESS server](/configuration/inbound/vless) and [vision](/configuration/outbound/vless#flow) support
* Add [reality TLS](/configuration/shared/tls/) support * Add [reality TLS](/configuration/shared/tls) support
* Add [NTP service](/configuration/ntp/) * Add [NTP service](/configuration/ntp)
* Add [DHCP DNS server](/configuration/dns/server/) support * Add [DHCP DNS server](/configuration/dns/server) support
* Add SSH [host key validation](/configuration/outbound/ssh/) support * Add SSH [host key validation](/configuration/outbound/ssh) support
* Add [query_type](/configuration/dns/rule/) DNS rule item * Add [query_type](/configuration/dns/rule) DNS rule item
* Add fallback support for v2ray transport * Add fallback support for v2ray transport
* Add custom TLS server support for http based v2ray transports * Add custom TLS server support for http based v2ray transports
* Add health check support for http-based v2ray transports * Add health check support for http-based v2ray transports
@@ -1510,7 +1078,7 @@ name.
#### 1.2-beta9 #### 1.2-beta9
* Introducing the [UDP over TCP protocol version 2](/configuration/shared/udp-over-tcp/) * Introducing the [UDP over TCP protocol version 2](/configuration/shared/udp-over-tcp)
* Add health check support for http-based v2ray transports * Add health check support for http-based v2ray transports
* Remove length limit on short_id for reality TLS config * Remove length limit on short_id for reality TLS config
* Fix bugs and update dependencies * Fix bugs and update dependencies
@@ -1527,7 +1095,7 @@ name.
#### 1.2-beta6 #### 1.2-beta6
* Introducing our [new iOS client application](/installation/clients/sfi/) * Introducing our [new iOS client application](/installation/clients/sfi)
* Add [platform options](/configuration/inbound/tun#platform) for tun inbound * Add [platform options](/configuration/inbound/tun#platform) for tun inbound
* Add custom TLS server support for http based v2ray transports * Add custom TLS server support for http based v2ray transports
* Add generate commands * Add generate commands
@@ -1540,8 +1108,8 @@ name.
#### 1.2-beta5 #### 1.2-beta5
* Add [VLESS server](/configuration/inbound/vless/) and [vision](/configuration/outbound/vless#flow) support * Add [VLESS server](/configuration/inbound/vless) and [vision](/configuration/outbound/vless#flow) support
* Add [reality TLS](/configuration/shared/tls/) support * Add [reality TLS](/configuration/shared/tls) support
* Fix match private address * Fix match private address
#### 1.1.6 #### 1.1.6
@@ -1556,7 +1124,7 @@ name.
#### 1.2-beta4 #### 1.2-beta4
* Add [NTP service](/configuration/ntp/) * Add [NTP service](/configuration/ntp)
* Add Add multiple server names and multi-user support for shadowtls * Add Add multiple server names and multi-user support for shadowtls
* Add strict mode support for shadowtls v3 * Add strict mode support for shadowtls v3
* Add uTLS support for shadowtls v3 * Add uTLS support for shadowtls v3
@@ -1576,9 +1144,9 @@ name.
#### 1.2-beta1 #### 1.2-beta1
* Add [DHCP DNS server](/configuration/dns/server/) support * Add [DHCP DNS server](/configuration/dns/server) support
* Add SSH [host key validation](/configuration/outbound/ssh/) support * Add SSH [host key validation](/configuration/outbound/ssh) support
* Add [query_type](/configuration/dns/rule/) DNS rule item * Add [query_type](/configuration/dns/rule) DNS rule item
* Add v2ray [user stats](/configuration/experimental#statsusers) api * Add v2ray [user stats](/configuration/experimental#statsusers) api
* Add new clash DNS query api * Add new clash DNS query api
* Improve vmess request * Improve vmess request
@@ -1807,7 +1375,7 @@ and [ShadowTLS outbound](/configuration/outbound/shadowtls#version)
#### 1.1-beta6 #### 1.1-beta6
* Add [URLTest outbound](/configuration/outbound/urltest/) * Add [URLTest outbound](/configuration/outbound/urltest)
* Fix bugs in 1.1-beta5 * Fix bugs in 1.1-beta5
#### 1.1-beta5 #### 1.1-beta5
@@ -1839,8 +1407,8 @@ The default tun stack is changed to system.
#### 1.1-beta4 #### 1.1-beta4
* Add internal simple-obfs and v2ray-plugin [Shadowsocks plugins](/configuration/outbound/shadowsocks#plugin) * Add internal simple-obfs and v2ray-plugin [Shadowsocks plugins](/configuration/outbound/shadowsocks#plugin)
* Add [ShadowsocksR outbound](/configuration/outbound/shadowsocksr/) * Add [ShadowsocksR outbound](/configuration/outbound/shadowsocksr)
* Add [VLESS outbound and XUDP](/configuration/outbound/vless/) * Add [VLESS outbound and XUDP](/configuration/outbound/vless)
* Skip wait for hysteria tcp handshake response * Skip wait for hysteria tcp handshake response
* Fix socks4 client * Fix socks4 client
* Fix hysteria inbound * Fix hysteria inbound
@@ -1867,7 +1435,7 @@ The default tun stack is changed to system.
*1*: *1*:
Switching modes using the Clash API, and `store-selected` are now supported, Switching modes using the Clash API, and `store-selected` are now supported,
see [Experimental](/configuration/experimental/). see [Experimental](/configuration/experimental).
*2*: *2*:
@@ -1948,15 +1516,15 @@ and [Listen Fields](/configuration/shared/listen#udp_fragment).
* Fix write trojan udp * Fix write trojan udp
* Fix DNS routing * Fix DNS routing
* Add attribute support for geosite * Add attribute support for geosite
* Update documentation for [Dial Fields](/configuration/shared/dial/) * Update documentation for [Dial Fields](/configuration/shared/dial)
#### 1.0-beta3 #### 1.0-beta3
* Add [chained inbound](/configuration/shared/listen#detour) support * Add [chained inbound](/configuration/shared/listen#detour) support
* Add process_path rule item * Add process_path rule item
* Add macOS redirect support * Add macOS redirect support
* Add ShadowTLS [Inbound](/configuration/inbound/shadowtls/), [Outbound](/configuration/outbound/shadowtls/) * Add ShadowTLS [Inbound](/configuration/inbound/shadowtls), [Outbound](/configuration/outbound/shadowtls)
and [Examples](/examples/shadowtls/) and [Examples](/examples/shadowtls)
* Fix search android package in non-owner users * Fix search android package in non-owner users
* Fix socksaddr type condition * Fix socksaddr type condition
* Fix smux session status * Fix smux session status
@@ -2000,7 +1568,7 @@ and [Listen Fields](/configuration/shared/listen#udp_fragment).
##### 2022/08/23 ##### 2022/08/23
* Add [V2Ray Transport](/configuration/shared/v2ray-transport/) support for VMess and Trojan * Add [V2Ray Transport](/configuration/shared/v2ray-transport) support for VMess and Trojan
* Allow plain http request in Naive inbound (It can now be used with nginx) * Allow plain http request in Naive inbound (It can now be used with nginx)
* Add proxy protocol support * Add proxy protocol support
* Free memory after start * Free memory after start
@@ -2009,13 +1577,13 @@ and [Listen Fields](/configuration/shared/listen#udp_fragment).
##### 2022/08/22 ##### 2022/08/22
* Add strategy setting for each [DNS server](/configuration/dns/server/) * Add strategy setting for each [DNS server](/configuration/dns/server)
* Add bind address to outbound options * Add bind address to outbound options
##### 2022/08/21 ##### 2022/08/21
* Add [Tor outbound](/configuration/outbound/tor/) * Add [Tor outbound](/configuration/outbound/tor)
* Add [SSH outbound](/configuration/outbound/ssh/) * Add [SSH outbound](/configuration/outbound/ssh)
##### 2022/08/20 ##### 2022/08/20
@@ -2029,8 +1597,8 @@ and [Listen Fields](/configuration/shared/listen#udp_fragment).
##### 2022/08/19 ##### 2022/08/19
* Add Hysteria [Inbound](/configuration/inbound/hysteria/) and [Outbund](/configuration/outbound/hysteria/) * Add Hysteria [Inbound](/configuration/inbound/hysteria) and [Outbund](/configuration/outbound/hysteria)
* Add [ACME TLS certificate issuer](/configuration/shared/tls/) * Add [ACME TLS certificate issuer](/configuration/shared/tls)
* Allow read config from stdin (-c stdin) * Allow read config from stdin (-c stdin)
* Update gVisor to 20220815.0 * Update gVisor to 20220815.0
@@ -2048,11 +1616,11 @@ and [Listen Fields](/configuration/shared/listen#udp_fragment).
##### 2022/08/16 ##### 2022/08/16
* Add ip_version (route/dns) rule item * Add ip_version (route/dns) rule item
* Add [WireGuard](/configuration/outbound/wireguard/) outbound * Add [WireGuard](/configuration/outbound/wireguard) outbound
##### 2022/08/15 ##### 2022/08/15
* Add uid, android user and package rules support in [Tun](/configuration/inbound/tun/) routing. * Add uid, android user and package rules support in [Tun](/configuration/inbound/tun) routing.
##### 2022/08/13 ##### 2022/08/13
@@ -2061,15 +1629,15 @@ and [Listen Fields](/configuration/shared/listen#udp_fragment).
##### 2022/08/12 ##### 2022/08/12
* Performance improvements * Performance improvements
* Add UoT option for [SOCKS](/configuration/outbound/socks/) outbound * Add UoT option for [SOCKS](/configuration/outbound/socks) outbound
##### 2022/08/11 ##### 2022/08/11
* Add UoT option for [Shadowsocks](/configuration/outbound/shadowsocks/) outbound, UoT support for all inbounds * Add UoT option for [Shadowsocks](/configuration/outbound/shadowsocks) outbound, UoT support for all inbounds
##### 2022/08/10 ##### 2022/08/10
* Add full-featured [Naive](/configuration/inbound/naive/) inbound * Add full-featured [Naive](/configuration/inbound/naive) inbound
* Fix default dns server option [#9] by iKirby * Fix default dns server option [#9] by iKirby
##### 2022/08/09 ##### 2022/08/09

View File

@@ -19,6 +19,7 @@ SFA provides an unprivileged TUN implementation through Android VpnService.
| `inet6_address` | :material-check: | / | | `inet6_address` | :material-check: | / |
| `mtu` | :material-check: | / | | `mtu` | :material-check: | / |
| `gso` | :material-close: | No permission | | `gso` | :material-close: | No permission |
| `gso_max_size` | :material-close: | No permission |
| `auto_route` | :material-check: | / | | `auto_route` | :material-check: | / |
| `strict_route` | :material-close: | Not implemented | | `strict_route` | :material-close: | Not implemented |
| `inet4_route_address` | :material-check: | / | | `inet4_route_address` | :material-check: | / |

View File

@@ -16,7 +16,6 @@ platform-specific function implementation, such as TUN transparent proxy impleme
* [Play Store](https://play.google.com/store/apps/details?id=io.nekohasekai.sfa) * [Play Store](https://play.google.com/store/apps/details?id=io.nekohasekai.sfa)
* [Play Store (Beta)](https://play.google.com/apps/testing/io.nekohasekai.sfa) * [Play Store (Beta)](https://play.google.com/apps/testing/io.nekohasekai.sfa)
* [GitHub Releases](https://github.com/SagerNet/sing-box/releases) * [GitHub Releases](https://github.com/SagerNet/sing-box/releases)
* [F-Droid](https://f-droid.org/packages/io.nekohasekai.sfa/) (Unified signature via reproducible builds)
## :material-source-repository: Source code ## :material-source-repository: Source code

View File

@@ -21,6 +21,7 @@ SFI/SFM/SFT provides an unprivileged TUN implementation through NetworkExtension
| `inet6_address` | :material-check: | / | | `inet6_address` | :material-check: | / |
| `mtu` | :material-check: | / | | `mtu` | :material-check: | / |
| `gso` | :material-close: | Not implemented | | `gso` | :material-close: | Not implemented |
| `gso_max_size` | :material-close: | Not implemented |
| `auto_route` | :material-check: | / | | `auto_route` | :material-check: | / |
| `strict_route` | :material-close: | Not implemented | | `strict_route` | :material-close: | Not implemented |
| `inet4_route_address` | :material-check: | / | | `inet4_route_address` | :material-check: | / |

View File

@@ -15,12 +15,7 @@ platform-specific function implementation, such as TUN transparent proxy impleme
## :material-download: Download ## :material-download: Download
* [App Store](https://apps.apple.com/us/app/sing-box/id6451272673) * [App Store](https://apps.apple.com/us/app/sing-box/id6451272673)
* ~~TestFlight (Beta)~~ * [TestFlight (Beta)](https://testflight.apple.com/join/AcqO44FH)
TestFlight quota is only available to [sponsors](https://github.com/sponsors/nekohasekai)
(one-time sponsorships are accepted).
Once you donate, you can get an invitation by sending us your Apple ID [via email](mailto:contact@sagernet.org),
or join our Telegram group for sponsors from [@yet_another_sponsor_bot](https://t.me/yet_another_sponsor_bot).
## :material-file-download: Download (macOS standalone version) ## :material-file-download: Download (macOS standalone version)

View File

@@ -2,11 +2,11 @@
Maintained by Project S to provide a unified experience and platform-specific functionality. Maintained by Project S to provide a unified experience and platform-specific functionality.
| Platform | Client | | Platform | Client |
|---------------------------------------|------------------------------------------| |---------------------------------------|-----------------------------------------|
| :material-android: Android | [sing-box for Android](./android/) | | :material-android: Android | [sing-box for Android](./android) |
| :material-apple: iOS/macOS/Apple tvOS | [sing-box for Apple platforms](./apple/) | | :material-apple: iOS/macOS/Apple tvOS | [sing-box for Apple platforms](./apple) |
| :material-laptop: Desktop | Working in progress | | :material-laptop: Desktop | Working in progress |
Some third-party projects that claim to use sing-box or use sing-box as a selling point are not listed here. The core Some third-party projects that claim to use sing-box or use sing-box as a selling point are not listed here. The core
motivation of the maintainers of such projects is to acquire more users, and even though they provide friendly VPN motivation of the maintainers of such projects is to acquire more users, and even though they provide friendly VPN

View File

@@ -4,8 +4,8 @@
| 平台 | 客户端 | | 平台 | 客户端 |
|---------------------------------------|-----------------------------------------| |---------------------------------------|-----------------------------------------|
| :material-android: Android | [sing-box for Android](./android/) | | :material-android: Android | [sing-box for Android](./android) |
| :material-apple: iOS/macOS/Apple tvOS | [sing-box for Apple platforms](./apple/) | | :material-apple: iOS/macOS/Apple tvOS | [sing-box for Apple platforms](./apple) |
| :material-laptop: Desktop | 施工中 | | :material-laptop: Desktop | 施工中 |
此处没有列出一些声称使用或以 sing-box 为卖点的第三方项目。此类项目维护者的动机是获得更多用户,即使它们提供友好的商业 此处没有列出一些声称使用或以 sing-box 为卖点的第三方项目。此类项目维护者的动机是获得更多用户,即使它们提供友好的商业

View File

@@ -6,9 +6,3 @@ icon: material/security
sing-box and official graphics clients do not collect or share personal data, sing-box and official graphics clients do not collect or share personal data,
and the data generated by the software is always on your device. and the data generated by the software is always on your device.
## Android
If your configuration contains `wifi_ssid` or `wifi_bssid` routing rules,
sing-box uses the location permission in the background
to get information about the connected Wi-Fi network to make them work.

View File

@@ -1,11 +1,3 @@
---
icon: material/new-box
---
!!! quote "Changes in sing-box 1.9.0"
:material-plus: [client_subnet](#client_subnet)
# DNS # DNS
### Structure ### Structure
@@ -21,7 +13,6 @@ icon: material/new-box
"disable_expire": false, "disable_expire": false,
"independent_cache": false, "independent_cache": false,
"reverse_mapping": false, "reverse_mapping": false,
"client_subnet": "",
"fakeip": {} "fakeip": {}
} }
} }
@@ -30,11 +21,11 @@ icon: material/new-box
### Fields ### Fields
| Key | Format | | Key | Format |
|----------|---------------------------------| |----------|--------------------------------|
| `server` | List of [DNS Server](./server/) | | `server` | List of [DNS Server](./server) |
| `rules` | List of [DNS Rule](./rule/) | | `rules` | List of [DNS Rule](./rule) |
| `fakeip` | [FakeIP](./fakeip/) | | `fakeip` | [FakeIP](./fakeip) |
#### final #### final
@@ -69,12 +60,6 @@ Stores a reverse mapping of IP addresses after responding to a DNS query in orde
Since this process relies on the act of resolving domain names by an application before making a request, it can be Since this process relies on the act of resolving domain names by an application before making a request, it can be
problematic in environments such as macOS, where DNS is proxied and cached by the system. problematic in environments such as macOS, where DNS is proxied and cached by the system.
#### client_subnet #### fakeip
!!! question "Since sing-box 1.9.0" [FakeIP](./fakeip) settings.
Append a `edns0-subnet` OPT extra record with the specified IP prefix to every query by default.
If value is an IP address instead of prefix, `/32` or `/128` will be appended automatically.
Can be overrides by `servers.[].client_subnet` or `rules.[].client_subnet`.

View File

@@ -1,11 +1,3 @@
---
icon: material/new-box
---
!!! quote "sing-box 1.9.0 中的更改"
:material-plus: [client_subnet](#client_subnet)
# DNS # DNS
### 结构 ### 结构
@@ -21,7 +13,6 @@ icon: material/new-box
"disable_expire": false, "disable_expire": false,
"independent_cache": false, "independent_cache": false,
"reverse_mapping": false, "reverse_mapping": false,
"client_subnet": "",
"fakeip": {} "fakeip": {}
} }
} }
@@ -30,10 +21,10 @@ icon: material/new-box
### 字段 ### 字段
| 键 | 格式 | | 键 | 格式 |
|----------|-------------------------| |----------|------------------------|
| `server` | 一组 [DNS 服务器](./server/) | | `server` | 一组 [DNS 服务器](./server) |
| `rules` | 一组 [DNS 规则](./rule/) | | `rules` | 一组 [DNS 规则](./rule) |
#### final #### final
@@ -67,16 +58,6 @@ icon: material/new-box
由于此过程依赖于应用程序在发出请求之前解析域名的行为,因此在 macOS 等 DNS 由系统代理和缓存的环境中可能会出现问题。 由于此过程依赖于应用程序在发出请求之前解析域名的行为,因此在 macOS 等 DNS 由系统代理和缓存的环境中可能会出现问题。
#### client_subnet
!!! question "自 sing-box 1.9.0 起"
默认情况下,将带有指定 IP 前缀的 `edns0-subnet` OPT 附加记录附加到每个查询。
如果值是 IP 地址而不是前缀,则会自动附加 `/32``/128`
可以被 `servers.[].client_subnet``rules.[].client_subnet` 覆盖。
#### fakeip #### fakeip
[FakeIP](./fakeip/) 设置。 [FakeIP](./fakeip) 设置。

View File

@@ -1,15 +1,7 @@
--- ---
icon: material/new-box icon: material/alert-decagram
--- ---
!!! quote "Changes in sing-box 1.9.0"
:material-plus: [geoip](#geoip)
:material-plus: [ip_cidr](#ip_cidr)
:material-plus: [ip_is_private](#ip_is_private)
:material-plus: [client_subnet](#client_subnet)
:material-plus: [rule_set_ipcidr_match_source](#rule_set_ipcidr_match_source)
!!! quote "Changes in sing-box 1.8.0" !!! quote "Changes in sing-box 1.8.0"
:material-plus: [rule_set](#rule_set) :material-plus: [rule_set](#rule_set)
@@ -61,19 +53,11 @@ icon: material/new-box
"source_geoip": [ "source_geoip": [
"private" "private"
], ],
"geoip": [
"cn"
],
"source_ip_cidr": [ "source_ip_cidr": [
"10.0.0.0/24", "10.0.0.0/24",
"192.168.0.1" "192.168.0.1"
], ],
"source_ip_is_private": false, "source_ip_is_private": false,
"ip_cidr": [
"10.0.0.0/24",
"192.168.0.1"
],
"ip_is_private": false,
"source_port": [ "source_port": [
12345 12345
], ],
@@ -117,15 +101,13 @@ icon: material/new-box
"geoip-cn", "geoip-cn",
"geosite-cn" "geosite-cn"
], ],
"rule_set_ipcidr_match_source": false,
"invert": false, "invert": false,
"outbound": [ "outbound": [
"direct" "direct"
], ],
"server": "local", "server": "local",
"disable_cache": false, "disable_cache": false,
"rewrite_ttl": 100, "rewrite_ttl": 100
"client_subnet": "127.0.0.1/24"
}, },
{ {
"type": "logical", "type": "logical",
@@ -133,8 +115,7 @@ icon: material/new-box
"rules": [], "rules": [],
"server": "local", "server": "local",
"disable_cache": false, "disable_cache": false,
"rewrite_ttl": 100, "rewrite_ttl": 100
"client_subnet": "127.0.0.1/24"
} }
] ]
} }
@@ -161,7 +142,7 @@ icon: material/new-box
#### inbound #### inbound
Tags of [Inbound](/configuration/inbound/). Tags of [Inbound](/configuration/inbound).
#### ip_version #### ip_version
@@ -285,9 +266,11 @@ Match Clash mode.
#### wifi_ssid #### wifi_ssid
<!-- md:version 1.7.0-beta.4 -->
!!! quote "" !!! quote ""
Only supported in graphical clients on Android and Apple platforms. Only supported in graphical clients on Android and iOS.
Match WiFi SSID. Match WiFi SSID.
@@ -295,7 +278,7 @@ Match WiFi SSID.
!!! quote "" !!! quote ""
Only supported in graphical clients on Android and Apple platforms. Only supported in graphical clients on Android and iOS.
Match WiFi BSSID. Match WiFi BSSID.
@@ -305,12 +288,6 @@ Match WiFi BSSID.
Match [Rule Set](/configuration/route/#rule_set). Match [Rule Set](/configuration/route/#rule_set).
#### rule_set_ipcidr_match_source
!!! question "Since sing-box 1.9.0"
Make `ipcidr` in rule sets match the source IP.
#### invert #### invert
Invert match result. Invert match result.
@@ -335,46 +312,6 @@ Disable cache and save cache in this query.
Rewrite TTL in DNS responses. Rewrite TTL in DNS responses.
#### client_subnet
!!! question "Since sing-box 1.9.0"
Append a `edns0-subnet` OPT extra record with the specified IP prefix to every query by default.
If value is an IP address instead of prefix, `/32` or `/128` will be appended automatically.
Will overrides `dns.client_subnet` and `servers.[].client_subnet`.
### Address Filter Fields
Only takes effect for IP address requests. When the query results do not match the address filtering rule items, the current rule will be skipped.
!!! info ""
`ip_cidr` items in included rule sets also takes effect as an address filtering field.
!!! note ""
Enable `experimental.cache_file.store_rdrc` to cache results.
#### geoip
!!! question "Since sing-box 1.9.0"
Match GeoIP with query response.
#### ip_cidr
!!! question "Since sing-box 1.9.0"
Match IP CIDR with query response.
#### ip_is_private
!!! question "Since sing-box 1.9.0"
Match private IP with query response.
### Logical Fields ### Logical Fields
#### type #### type

View File

@@ -1,15 +1,7 @@
--- ---
icon: material/new-box icon: material/alert-decagram
--- ---
!!! quote "sing-box 1.9.0 中的更改"
:material-plus: [geoip](#geoip)
:material-plus: [ip_cidr](#ip_cidr)
:material-plus: [ip_is_private](#ip_is_private)
:material-plus: [client_subnet](#client_subnet)
:material-plus: [rule_set_ipcidr_match_source](#rule_set_ipcidr_match_source)
!!! quote "sing-box 1.8.0 中的更改" !!! quote "sing-box 1.8.0 中的更改"
:material-plus: [rule_set](#rule_set) :material-plus: [rule_set](#rule_set)
@@ -61,19 +53,10 @@ icon: material/new-box
"source_geoip": [ "source_geoip": [
"private" "private"
], ],
"geoip": [
"cn"
],
"source_ip_cidr": [ "source_ip_cidr": [
"10.0.0.0/24", "10.0.0.0/24"
"192.168.0.1"
], ],
"source_ip_is_private": false, "source_ip_is_private": false,
"ip_cidr": [
"10.0.0.0/24",
"192.168.0.1"
],
"ip_is_private": false,
"source_port": [ "source_port": [
12345 12345
], ],
@@ -117,22 +100,19 @@ icon: material/new-box
"geoip-cn", "geoip-cn",
"geosite-cn" "geosite-cn"
], ],
"rule_set_ipcidr_match_source": false,
"invert": false, "invert": false,
"outbound": [ "outbound": [
"direct" "direct"
], ],
"server": "local", "server": "local",
"disable_cache": false, "disable_cache": false
"client_subnet": "127.0.0.1/24"
}, },
{ {
"type": "logical", "type": "logical",
"mode": "and", "mode": "and",
"rules": [], "rules": [],
"server": "local", "server": "local",
"disable_cache": false, "disable_cache": false
"client_subnet": "127.0.0.1/24"
} }
] ]
} }
@@ -159,7 +139,7 @@ icon: material/new-box
#### inbound #### inbound
[入站](/zh/configuration/inbound/) 标签. [入站](/zh/configuration/inbound) 标签.
#### ip_version #### ip_version
@@ -285,7 +265,7 @@ DNS 查询类型。值可以为整数或者类型名称字符串。
!!! quote "" !!! quote ""
仅在 Android 与 Apple 平台图形客户端中支持。 仅在 Android 与 iOS 的图形客户端中支持。
匹配 WiFi SSID。 匹配 WiFi SSID。
@@ -293,7 +273,7 @@ DNS 查询类型。值可以为整数或者类型名称字符串。
!!! quote "" !!! quote ""
仅在 Android 与 Apple 平台图形客户端中支持。 仅在 Android 与 iOS 的图形客户端中支持。
匹配 WiFi BSSID。 匹配 WiFi BSSID。
@@ -303,12 +283,6 @@ DNS 查询类型。值可以为整数或者类型名称字符串。
匹配[规则集](/zh/configuration/route/#rule_set)。 匹配[规则集](/zh/configuration/route/#rule_set)。
#### rule_set_ipcidr_match_source
!!! question "自 sing-box 1.9.0 起"
使规则集中的 `ipcidr` 规则匹配源 IP。
#### invert #### invert
反选匹配结果。 反选匹配结果。
@@ -333,46 +307,6 @@ DNS 查询类型。值可以为整数或者类型名称字符串。
重写 DNS 回应中的 TTL。 重写 DNS 回应中的 TTL。
#### client_subnet
!!! question "自 sing-box 1.9.0 起"
默认情况下,将带有指定 IP 前缀的 `edns0-subnet` OPT 附加记录附加到每个查询。
如果值是 IP 地址而不是前缀,则会自动附加 `/32``/128`
将覆盖 `dns.client_subnet``servers.[].client_subnet`
### 地址筛选字段
仅对IP地址请求生效。 当查询结果与地址筛选规则项不匹配时,将跳过当前规则。
!!! info ""
引用的规则集中的 `ip_cidr` 项也作为地址筛选字段生效。
!!! note ""
启用 `experimental.cache_file.store_rdrc` 以缓存结果。
#### geoip
!!! question "自 sing-box 1.9.0 起"
与查询响应匹配 GeoIP。
#### ip_cidr
!!! question "自 sing-box 1.9.0 起"
与查询相应匹配 IP CIDR。
#### ip_is_private
!!! question "自 sing-box 1.9.0 起"
与查询响应匹配非公开 IP。
### 逻辑字段 ### 逻辑字段
#### type #### type
@@ -385,4 +319,4 @@ DNS 查询类型。值可以为整数或者类型名称字符串。
#### rules #### rules
包括的规则。 包括的规则。

View File

@@ -1,11 +1,3 @@
---
icon: material/new-box
---
!!! quote "Changes in sing-box 1.9.0"
:material-plus: [client_subnet](#client_subnet)
### Structure ### Structure
```json ```json
@@ -13,17 +5,17 @@ icon: material/new-box
"dns": { "dns": {
"servers": [ "servers": [
{ {
"tag": "", "tag": "google",
"address": "", "address": "tls://dns.google",
"address_resolver": "", "address_resolver": "local",
"address_strategy": "", "address_strategy": "prefer_ipv4",
"strategy": "", "strategy": "ipv4_only",
"detour": "", "detour": "direct"
"client_subnet": ""
} }
] ]
} }
} }
``` ```
### Fields ### Fields
@@ -38,18 +30,18 @@ The tag of the dns server.
The address of the dns server. The address of the dns server.
| Protocol | Format | | Protocol | Format |
|--------------------------------------|-------------------------------| |-------------------------------------|-------------------------------|
| `System` | `local` | | `System` | `local` |
| `TCP` | `tcp://1.0.0.1` | | `TCP` | `tcp://1.0.0.1` |
| `UDP` | `8.8.8.8` `udp://8.8.4.4` | | `UDP` | `8.8.8.8` `udp://8.8.4.4` |
| `TLS` | `tls://dns.google` | | `TLS` | `tls://dns.google` |
| `HTTPS` | `https://1.1.1.1/dns-query` | | `HTTPS` | `https://1.1.1.1/dns-query` |
| `QUIC` | `quic://dns.adguard.com` | | `QUIC` | `quic://dns.adguard.com` |
| `HTTP3` | `h3://8.8.8.8/dns-query` | | `HTTP3` | `h3://8.8.8.8/dns-query` |
| `RCode` | `rcode://refused` | | `RCode` | `rcode://refused` |
| `DHCP` | `dhcp://auto` or `dhcp://en0` | | `DHCP` | `dhcp://auto` or `dhcp://en0` |
| [FakeIP](/configuration/dns/fakeip/) | `fakeip` | | [FakeIP](/configuration/dns/fakeip) | `fakeip` |
!!! warning "" !!! warning ""
@@ -88,22 +80,10 @@ Default domain strategy for resolving the domain names.
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`. One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
Take no effect if overridden by other settings. Take no effect if override by other settings.
#### detour #### detour
Tag of an outbound for connecting to the dns server. Tag of an outbound for connecting to the dns server.
Default outbound will be used if empty. Default outbound will be used if empty.
#### client_subnet
!!! question "Since sing-box 1.9.0"
Append a `edns0-subnet` OPT extra record with the specified IP prefix to every query by default.
If value is an IP address instead of prefix, `/32` or `/128` will be appended automatically.
Can be overrides by `rules.[].client_subnet`.
Will overrides `dns.client_subnet`.

View File

@@ -1,11 +1,3 @@
---
icon: material/new-box
---
!!! quote "sing-box 1.9.0 中的更改"
:material-plus: [client_subnet](#client_subnet)
### 结构 ### 结构
```json ```json
@@ -13,17 +5,17 @@ icon: material/new-box
"dns": { "dns": {
"servers": [ "servers": [
{ {
"tag": "", "tag": "google",
"address": "", "address": "tls://dns.google",
"address_resolver": "", "address_resolver": "local",
"address_strategy": "", "address_strategy": "prefer_ipv4",
"strategy": "", "strategy": "ipv4_only",
"detour": "", "detour": "direct"
"client_subnet": ""
} }
] ]
} }
} }
``` ```
### 字段 ### 字段
@@ -38,18 +30,18 @@ DNS 服务器的标签。
DNS 服务器的地址。 DNS 服务器的地址。
| 协议 | 格式 | | 协议 | 格式 |
|--------------------------------------|------------------------------| |-------------------------------------|------------------------------|
| `System` | `local` | | `System` | `local` |
| `TCP` | `tcp://1.0.0.1` | | `TCP` | `tcp://1.0.0.1` |
| `UDP` | `8.8.8.8` `udp://8.8.4.4` | | `UDP` | `8.8.8.8` `udp://8.8.4.4` |
| `TLS` | `tls://dns.google` | | `TLS` | `tls://dns.google` |
| `HTTPS` | `https://1.1.1.1/dns-query` | | `HTTPS` | `https://1.1.1.1/dns-query` |
| `QUIC` | `quic://dns.adguard.com` | | `QUIC` | `quic://dns.adguard.com` |
| `HTTP3` | `h3://8.8.8.8/dns-query` | | `HTTP3` | `h3://8.8.8.8/dns-query` |
| `RCode` | `rcode://refused` | | `RCode` | `rcode://refused` |
| `DHCP` | `dhcp://auto``dhcp://en0` | | `DHCP` | `dhcp://auto``dhcp://en0` |
| [FakeIP](/configuration/dns/fakeip/) | `fakeip` | | [FakeIP](/configuration/dns/fakeip) | `fakeip` |
!!! warning "" !!! warning ""
@@ -95,15 +87,3 @@ DNS 服务器的地址。
用于连接到 DNS 服务器的出站的标签。 用于连接到 DNS 服务器的出站的标签。
如果为空,将使用默认出站。 如果为空,将使用默认出站。
#### client_subnet
!!! question "自 sing-box 1.9.0 起"
默认情况下,将带有指定 IP 前缀的 `edns0-subnet` OPT 附加记录附加到每个查询。
如果值是 IP 地址而不是前缀,则会自动附加 `/32``/128`
可以被 `rules.[].client_subnet` 覆盖。
将覆盖 `dns.client_subnet`

View File

@@ -4,11 +4,6 @@ icon: material/new-box
!!! question "Since sing-box 1.8.0" !!! question "Since sing-box 1.8.0"
!!! quote "Changes in sing-box 1.9.0"
:material-plus: [store_rdrc](#store_rdrc)
:material-plus: [rdrc_timeout](#rdrc_timeout)
### Structure ### Structure
```json ```json
@@ -16,9 +11,7 @@ icon: material/new-box
"enabled": true, "enabled": true,
"path": "", "path": "",
"cache_id": "", "cache_id": "",
"store_fakeip": false, "store_fakeip": false
"store_rdrc": false,
"rdrc_timeout": ""
} }
``` ```
@@ -36,23 +29,6 @@ Path to the cache file.
#### cache_id #### cache_id
Identifier in the cache file Identifier in cache file.
If not empty, configuration specified data will use a separate store keyed by it. If not empty, configuration specified data will use a separate store keyed by it.
#### store_fakeip
Store fakeip in the cache file
#### store_rdrc
Store rejected DNS response cache in the cache file
The check results of [Address filter DNS rule items](/configuration/dns/rule/#address-filter-fields)
will be cached until expiration.
#### rdrc_timeout
Timeout of rejected DNS response cache.
`7d` is used by default.

View File

@@ -4,11 +4,6 @@ icon: material/new-box
!!! question "自 sing-box 1.8.0 起" !!! question "自 sing-box 1.8.0 起"
!!! quote "sing-box 1.9.0 中的更改"
:material-plus: [store_rdrc](#store_rdrc)
:material-plus: [rdrc_timeout](#rdrc_timeout)
### 结构 ### 结构
```json ```json
@@ -16,9 +11,7 @@ icon: material/new-box
"enabled": true, "enabled": true,
"path": "", "path": "",
"cache_id": "", "cache_id": "",
"store_fakeip": false, "store_fakeip": false
"store_rdrc": false,
"rdrc_timeout": ""
} }
``` ```
@@ -37,19 +30,3 @@ icon: material/new-box
缓存文件中的标识符。 缓存文件中的标识符。
如果不为空,配置特定的数据将使用由其键控的单独存储。 如果不为空,配置特定的数据将使用由其键控的单独存储。
#### store_fakeip
将 fakeip 存储在缓存文件中。
#### store_rdrc
将拒绝的 DNS 响应缓存存储在缓存文件中。
[地址筛选 DNS 规则项](/zh/configuration/dns/rule/#_3) 的检查结果将被缓存至过期。
#### rdrc_timeout
拒绝的 DNS 响应缓存超时。
默认使用 `7d`

View File

@@ -1,3 +1,7 @@
---
icon: material/alert-decagram
---
!!! quote "Changes in sing-box 1.8.0" !!! quote "Changes in sing-box 1.8.0"
:material-delete-alert: [store_mode](#store_mode) :material-delete-alert: [store_mode](#store_mode)

View File

@@ -1,3 +1,7 @@
---
icon: material/alert-decagram
---
!!! quote "sing-box 1.8.0 中的更改" !!! quote "sing-box 1.8.0 中的更改"
:material-delete-alert: [store_mode](#store_mode) :material-delete-alert: [store_mode](#store_mode)

View File

@@ -1,3 +1,7 @@
---
icon: material/alert-decagram
---
# Experimental # Experimental
!!! quote "Changes in sing-box 1.8.0" !!! quote "Changes in sing-box 1.8.0"
@@ -21,6 +25,6 @@
| Key | Format | | Key | Format |
|--------------|----------------------------| |--------------|----------------------------|
| `cache_file` | [Cache File](./cache-file/) | | `cache_file` | [Cache File](./cache-file) |
| `clash_api` | [Clash API](./clash-api/) | | `clash_api` | [Clash API](./clash-api) |
| `v2ray_api` | [V2Ray API](./v2ray-api/) | | `v2ray_api` | [V2Ray API](./v2ray-api) |

View File

@@ -1,3 +1,7 @@
---
icon: material/alert-decagram
---
# 实验性 # 实验性
!!! quote "sing-box 1.8.0 中的更改" !!! quote "sing-box 1.8.0 中的更改"
@@ -21,6 +25,6 @@
| 键 | 格式 | | 键 | 格式 |
|--------------|--------------------------| |--------------|--------------------------|
| `cache_file` | [缓存文件](./cache-file/) | | `cache_file` | [缓存文件](./cache-file) |
| `clash_api` | [Clash API](./clash-api/) | | `clash_api` | [Clash API](./clash-api) |
| `v2ray_api` | [V2Ray API](./v2ray-api/) | | `v2ray_api` | [V2Ray API](./v2ray-api) |

View File

@@ -17,7 +17,7 @@
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.
### Fields ### Fields

View File

@@ -20,7 +20,7 @@
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.
### Fields ### Fields
@@ -42,6 +42,6 @@ No authentication required if empty.
!!! warning "" !!! warning ""
To work on Android and Apple platforms without privileges, use tun.platform.http_proxy instead. To work on Android and iOS without privileges, use tun.platform.http_proxy instead.
Automatically set system proxy configuration when start and clean up when stop. Automatically set system proxy configuration when start and clean up when stop.

View File

@@ -31,7 +31,7 @@
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.
### Fields ### Fields

View File

@@ -35,7 +35,7 @@
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.
### Fields ### Fields

View File

@@ -15,24 +15,24 @@
### Fields ### Fields
| Type | Format | Injectable | | Type | Format | Injectable |
|---------------|-------------------------------|------------| |---------------|------------------------------|------------|
| `direct` | [Direct](./direct/) | X | | `direct` | [Direct](./direct) | X |
| `mixed` | [Mixed](./mixed/) | TCP | | `mixed` | [Mixed](./mixed) | TCP |
| `socks` | [SOCKS](./socks/) | TCP | | `socks` | [SOCKS](./socks) | TCP |
| `http` | [HTTP](./http/) | TCP | | `http` | [HTTP](./http) | TCP |
| `shadowsocks` | [Shadowsocks](./shadowsocks/) | TCP | | `shadowsocks` | [Shadowsocks](./shadowsocks) | TCP |
| `vmess` | [VMess](./vmess/) | TCP | | `vmess` | [VMess](./vmess) | TCP |
| `trojan` | [Trojan](./trojan/) | TCP | | `trojan` | [Trojan](./trojan) | TCP |
| `naive` | [Naive](./naive/) | X | | `naive` | [Naive](./naive) | X |
| `hysteria` | [Hysteria](./hysteria/) | X | | `hysteria` | [Hysteria](./hysteria) | X |
| `shadowtls` | [ShadowTLS](./shadowtls/) | TCP | | `shadowtls` | [ShadowTLS](./shadowtls) | TCP |
| `tuic` | [TUIC](./tuic/) | X | | `tuic` | [TUIC](./tuic) | X |
| `hysteria2` | [Hysteria2](./hysteria2/) | X | | `hysteria2` | [Hysteria2](./hysteria2) | X |
| `vless` | [VLESS](./vless/) | TCP | | `vless` | [VLESS](./vless) | TCP |
| `tun` | [Tun](./tun/) | X | | `tun` | [Tun](./tun) | X |
| `redirect` | [Redirect](./redirect/) | X | | `redirect` | [Redirect](./redirect) | X |
| `tproxy` | [TProxy](./tproxy/) | X | | `tproxy` | [TProxy](./tproxy) | X |
#### tag #### tag

View File

@@ -17,22 +17,22 @@
| 类型 | 格式 | 注入支持 | | 类型 | 格式 | 注入支持 |
|---------------|------------------------------|------| |---------------|------------------------------|------|
| `direct` | [Direct](./direct/) | X | | `direct` | [Direct](./direct) | X |
| `mixed` | [Mixed](./mixed/) | TCP | | `mixed` | [Mixed](./mixed) | TCP |
| `socks` | [SOCKS](./socks/) | TCP | | `socks` | [SOCKS](./socks) | TCP |
| `http` | [HTTP](./http/) | TCP | | `http` | [HTTP](./http) | TCP |
| `shadowsocks` | [Shadowsocks](./shadowsocks/) | TCP | | `shadowsocks` | [Shadowsocks](./shadowsocks) | TCP |
| `vmess` | [VMess](./vmess/) | TCP | | `vmess` | [VMess](./vmess) | TCP |
| `trojan` | [Trojan](./trojan/) | TCP | | `trojan` | [Trojan](./trojan) | TCP |
| `naive` | [Naive](./naive/) | X | | `naive` | [Naive](./naive) | X |
| `hysteria` | [Hysteria](./hysteria/) | X | | `hysteria` | [Hysteria](./hysteria) | X |
| `shadowtls` | [ShadowTLS](./shadowtls/) | TCP | | `shadowtls` | [ShadowTLS](./shadowtls) | TCP |
| `tuic` | [TUIC](./tuic/) | X | | `tuic` | [TUIC](./tuic) | X |
| `hysteria2` | [Hysteria2](./hysteria2/) | X | | `hysteria2` | [Hysteria2](./hysteria2) | X |
| `vless` | [VLESS](./vless/) | TCP | | `vless` | [VLESS](./vless) | TCP |
| `tun` | [Tun](./tun/) | X | | `tun` | [Tun](./tun) | X |
| `redirect` | [Redirect](./redirect/) | X | | `redirect` | [Redirect](./redirect) | X |
| `tproxy` | [TProxy](./tproxy/) | X | | `tproxy` | [TProxy](./tproxy) | X |
#### tag #### tag

View File

@@ -21,7 +21,7 @@
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.
### Fields ### Fields
@@ -39,6 +39,6 @@ No authentication required if empty.
!!! warning "" !!! warning ""
To work on Android and Apple platforms without privileges, use tun.platform.http_proxy instead. To work on Android and iOS without privileges, use tun.platform.http_proxy instead.
Automatically set system proxy configuration when start and clean up when stop. Automatically set system proxy configuration when start and clean up when stop.

View File

@@ -20,7 +20,7 @@
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.
### Fields ### Fields

View File

@@ -15,4 +15,4 @@
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.

View File

@@ -50,7 +50,7 @@
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.
### Fields ### Fields

View File

@@ -50,7 +50,7 @@
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.
### 字段 ### 字段

View File

@@ -35,7 +35,7 @@
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.
### Fields ### Fields
@@ -66,11 +66,11 @@ Only available in the ShadowTLS protocol 3.
==Required== ==Required==
Handshake server address and [Dial options](/configuration/shared/dial/). Handshake server address and [Dial options](/configuration/shared/dial).
#### handshake_for_server_name #### handshake_for_server_name
Handshake server address and [Dial options](/configuration/shared/dial/) for specific server name. Handshake server address and [Dial options](/configuration/shared/dial) for specific server name.
Only available in the ShadowTLS protocol 2/3. Only available in the ShadowTLS protocol 2/3.

View File

@@ -20,7 +20,7 @@
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.
### Fields ### Fields

View File

@@ -17,7 +17,7 @@
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.
### Fields ### Fields

View File

@@ -31,7 +31,7 @@
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.
### Fields ### Fields
@@ -65,4 +65,4 @@ See [Multiplex](/configuration/shared/multiplex#inbound) for details.
#### transport #### transport
V2Ray Transport configuration, see [V2Ray Transport](/configuration/shared/v2ray-transport/). V2Ray Transport configuration, see [V2Ray Transport](/configuration/shared/v2ray-transport).

View File

@@ -67,4 +67,4 @@ TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
#### transport #### transport
V2Ray 传输配置,参阅 [V2Ray 传输层](/zh/configuration/shared/v2ray-transport/)。 V2Ray 传输配置,参阅 [V2Ray 传输层](/zh/configuration/shared/v2ray-transport)。

View File

@@ -24,7 +24,7 @@
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.
### Fields ### Fields

View File

@@ -1,15 +1,11 @@
--- ---
icon: material/new-box icon: material/alert-decagram
--- ---
!!! quote "Changes in sing-box 1.9.0"
:material-plus: [platform.http_proxy.bypass_domain](#platformhttp_proxybypass_domain)
:material-plus: [platform.http_proxy.match_domain](#platformhttp_proxymatch_domain)
!!! quote "Changes in sing-box 1.8.0" !!! quote "Changes in sing-box 1.8.0"
:material-plus: [gso](#gso) :material-plus: [gso](#gso)
:material-plus: [gso_max_size](#gso_max_size)
:material-alert-decagram: [stack](#stack) :material-alert-decagram: [stack](#stack)
!!! quote "" !!! quote ""
@@ -27,6 +23,7 @@ icon: material/new-box
"inet6_address": "fdfe:dcba:9876::1/126", "inet6_address": "fdfe:dcba:9876::1/126",
"mtu": 9000, "mtu": 9000,
"gso": false, "gso": false,
"gso_max_size": 65536,
"auto_route": true, "auto_route": true,
"strict_route": true, "strict_route": true,
"inet4_route_address": [ "inet4_route_address": [
@@ -44,7 +41,6 @@ icon: material/new-box
"fc00::/7" "fc00::/7"
], ],
"endpoint_independent_nat": false, "endpoint_independent_nat": false,
"udp_timeout": "5m",
"stack": "system", "stack": "system",
"include_interface": [ "include_interface": [
"lan0" "lan0"
@@ -78,9 +74,7 @@ icon: material/new-box
"http_proxy": { "http_proxy": {
"enabled": false, "enabled": false,
"server": "127.0.0.1", "server": "127.0.0.1",
"server_port": 8080, "server_port": 8080
"bypass_domain": [],
"match_domain": []
} }
}, },
@@ -126,6 +120,18 @@ The maximum transmission unit.
Enable generic segmentation offload. Enable generic segmentation offload.
#### gso_max_size
!!! question "Since sing-box 1.8.0"
!!! quote ""
Only supported on Linux.
Maximum GSO packet size.
`65536` is used by default.
#### auto_route #### auto_route
Set the default route to the Tun. Set the default route to the Tun.
@@ -147,7 +153,7 @@ Enforce strict routing rules when `auto_route` is enabled:
* Let unsupported network unreachable * Let unsupported network unreachable
* Route all connections to tun * Route all connections to tun
It prevents address leaks and makes DNS hijacking work on Android. It prevents address leaks and makes DNS hijacking work on Android, but your device will not be accessible by others.
*In Windows*: *In Windows*:
@@ -267,38 +273,6 @@ Platform-specific settings, provided by client applications.
System HTTP proxy settings. System HTTP proxy settings.
#### platform.http_proxy.enabled
Enable system HTTP proxy.
#### platform.http_proxy.server
==Required==
HTTP proxy server address.
#### platform.http_proxy.server_port
==Required==
HTTP proxy server port.
#### platform.http_proxy.bypass_domain
!!! note ""
On Apple platforms, `bypass_domain` items matches hostname **suffixes**.
Hostnames that bypass the HTTP proxy.
#### platform.http_proxy.match_domain
!!! quote ""
Only supported in graphical clients on Apple platforms.
Hostnames that use the HTTP proxy.
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.

View File

@@ -1,15 +1,11 @@
--- ---
icon: material/new-box icon: material/alert-decagram
--- ---
!!! quote "sing-box 1.9.0 中的更改"
:material-plus: [platform.http_proxy.bypass_domain](#platformhttp_proxybypass_domain)
:material-plus: [platform.http_proxy.match_domain](#platformhttp_proxymatch_domain)
!!! quote "sing-box 1.8.0 中的更改" !!! quote "sing-box 1.8.0 中的更改"
:material-plus: [gso](#gso) :material-plus: [gso](#gso)
:material-plus: [gso_max_size](#gso_max_size)
:material-alert-decagram: [stack](#stack) :material-alert-decagram: [stack](#stack)
!!! quote "" !!! quote ""
@@ -27,6 +23,7 @@ icon: material/new-box
"inet6_address": "fdfe:dcba:9876::1/126", "inet6_address": "fdfe:dcba:9876::1/126",
"mtu": 9000, "mtu": 9000,
"gso": false, "gso": false,
"gso_max_size": 65536,
"auto_route": true, "auto_route": true,
"strict_route": true, "strict_route": true,
"inet4_route_address": [ "inet4_route_address": [
@@ -44,7 +41,6 @@ icon: material/new-box
"fc00::/7" "fc00::/7"
], ],
"endpoint_independent_nat": false, "endpoint_independent_nat": false,
"udp_timeout": "5m",
"stack": "system", "stack": "system",
"include_interface": [ "include_interface": [
"lan0" "lan0"
@@ -78,9 +74,7 @@ icon: material/new-box
"http_proxy": { "http_proxy": {
"enabled": false, "enabled": false,
"server": "127.0.0.1", "server": "127.0.0.1",
"server_port": 8080, "server_port": 8080
"bypass_domain": [],
"match_domain": []
} }
}, },
@@ -126,6 +120,18 @@ tun 接口的 IPv6 前缀。
启用通用分段卸载。 启用通用分段卸载。
#### gso_max_size
!!! question "自 sing-box 1.8.0 起"
!!! quote ""
仅支持 Linux。
通用分段卸载包的最大大小。
默认使用 `65536`
#### auto_route #### auto_route
设置到 Tun 的默认路由。 设置到 Tun 的默认路由。
@@ -147,7 +153,7 @@ tun 接口的 IPv6 前缀。
* 让不支持的网络无法到达 * 让不支持的网络无法到达
* 将所有连接路由到 tun * 将所有连接路由到 tun
它可以防止地址泄漏,并使 DNS 劫持在 Android 上工作。 它可以防止地址泄漏,并使 DNS 劫持在 Android 上工作,但你的设备将无法其他设备被访问
*在 Windows 中*: *在 Windows 中*:
@@ -264,38 +270,6 @@ TCP/IP 栈。
系统 HTTP 代理设置。 系统 HTTP 代理设置。
##### platform.http_proxy.enabled
启用系统 HTTP 代理。
##### platform.http_proxy.server
==必填==
系统 HTTP 代理服务器地址。
##### platform.http_proxy.server_port
==必填==
系统 HTTP 代理服务器端口。
##### platform.http_proxy.bypass_domain
!!! note ""
在 Apple 平台,`bypass_domain` 项匹配主机名 **后缀**.
绕过代理的主机名列表。
##### platform.http_proxy.match_domain
!!! quote ""
仅在 Apple 平台图形客户端中支持。
代理的主机名列表。
### 监听字段 ### 监听字段
参阅 [监听字段](/zh/configuration/shared/listen/)。 参阅 [监听字段](/zh/configuration/shared/listen/)。

View File

@@ -22,7 +22,7 @@
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.
### Fields ### Fields
@@ -56,4 +56,4 @@ See [Multiplex](/configuration/shared/multiplex#inbound) for details.
#### transport #### transport
V2Ray Transport configuration, see [V2Ray Transport](/configuration/shared/v2ray-transport/). V2Ray Transport configuration, see [V2Ray Transport](/configuration/shared/v2ray-transport).

View File

@@ -56,4 +56,4 @@ TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
#### transport #### transport
V2Ray 传输配置,参阅 [V2Ray 传输层](/zh/configuration/shared/v2ray-transport/)。 V2Ray 传输配置,参阅 [V2Ray 传输层](/zh/configuration/shared/v2ray-transport)。

View File

@@ -22,7 +22,7 @@
### Listen Fields ### Listen Fields
See [Listen Fields](/configuration/shared/listen/) for details. See [Listen Fields](/configuration/shared/listen) for details.
### Fields ### Fields
@@ -51,4 +51,4 @@ See [Multiplex](/configuration/shared/multiplex#inbound) for details.
#### transport #### transport
V2Ray Transport configuration, see [V2Ray Transport](/configuration/shared/v2ray-transport/). V2Ray Transport configuration, see [V2Ray Transport](/configuration/shared/v2ray-transport).

View File

@@ -51,4 +51,4 @@ TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
#### transport #### transport
V2Ray 传输配置,参阅 [V2Ray 传输层](/zh/configuration/shared/v2ray-transport/)。 V2Ray 传输配置,参阅 [V2Ray 传输层](/zh/configuration/shared/v2ray-transport)。

View File

@@ -18,15 +18,15 @@ sing-box uses JSON for configuration files.
### Fields ### Fields
| Key | Format | | Key | Format |
|----------------|---------------------------------| |----------------|--------------------------------|
| `log` | [Log](./log/) | | `log` | [Log](./log) |
| `dns` | [DNS](./dns/) | | `dns` | [DNS](./dns) |
| `ntp` | [NTP](./ntp/) | | `ntp` | [NTP](./ntp) |
| `inbounds` | [Inbound](./inbound/) | | `inbounds` | [Inbound](./inbound) |
| `outbounds` | [Outbound](./outbound/) | | `outbounds` | [Outbound](./outbound) |
| `route` | [Route](./route/) | | `route` | [Route](./route) |
| `experimental` | [Experimental](./experimental/) | | `experimental` | [Experimental](./experimental) |
### Check ### Check

View File

@@ -17,14 +17,14 @@ sing-box 使用 JSON 作为配置文件格式。
### 字段 ### 字段
| Key | Format | | Key | Format |
|----------------|------------------------| |----------------|-----------------------|
| `log` | [日志](./log/) | | `log` | [日志](./log) |
| `dns` | [DNS](./dns/) | | `dns` | [DNS](./dns) |
| `inbounds` | [入站](./inbound/) | | `inbounds` | [入站](./inbound) |
| `outbounds` | [出站](./outbound/) | | `outbounds` | [出站](./outbound) |
| `route` | [路由](./route/) | | `route` | [路由](./route) |
| `experimental` | [实验性](./experimental/) | | `experimental` | [实验性](./experimental) |
### 检查 ### 检查

View File

@@ -47,4 +47,4 @@ Time synchronization interval.
### Dial Fields ### Dial Fields
See [Dial Fields](/configuration/shared/dial/) for details. See [Dial Fields](/configuration/shared/dial) for details.

Some files were not shown because too many files have changed in this diff Show More