From 8b404b5a4c0843b06d842e4eefdfd1647c615668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sat, 17 Jan 2026 05:10:43 +0800 Subject: [PATCH 01/20] Update Go to 1.25.6 --- .github/setup_go_for_windows7.sh | 2 +- .github/workflows/build.yml | 10 +++++----- .github/workflows/linux.yml | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/setup_go_for_windows7.sh b/.github/setup_go_for_windows7.sh index a04a644f..de440afa 100755 --- a/.github/setup_go_for_windows7.sh +++ b/.github/setup_go_for_windows7.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -VERSION="1.25.5" +VERSION="1.25.6" mkdir -p $HOME/go cd $HOME/go diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7ed9ba6a..5ef5ae20 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,7 +46,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: ^1.25.5 + go-version: ^1.25.6 - name: Check input version if: github.event_name == 'workflow_dispatch' run: |- @@ -110,7 +110,7 @@ jobs: if: ${{ ! (matrix.legacy_win7 || matrix.legacy_go124) }} uses: actions/setup-go@v5 with: - go-version: ^1.25.5 + go-version: ^1.25.6 - name: Setup Go 1.24 if: matrix.legacy_go124 uses: actions/setup-go@v5 @@ -300,7 +300,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: ^1.25.5 + go-version: ^1.25.6 - name: Setup Android NDK id: setup-ndk uses: nttld/setup-ndk@v1 @@ -380,7 +380,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: ^1.25.5 + go-version: ^1.25.6 - name: Setup Android NDK id: setup-ndk uses: nttld/setup-ndk@v1 @@ -479,7 +479,7 @@ jobs: if: matrix.if uses: actions/setup-go@v5 with: - go-version: ^1.25.5 + go-version: ^1.25.6 - name: Set tag if: matrix.if run: |- diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 19b2967b..0f009697 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -30,7 +30,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: ^1.25.5 + go-version: ^1.25.6 - name: Check input version if: github.event_name == 'workflow_dispatch' run: |- @@ -71,7 +71,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: ^1.25.5 + go-version: ^1.25.6 - name: Setup Android NDK if: matrix.os == 'android' uses: nttld/setup-ndk@v1 From 51ce402dbb14469bed8ae041afa7e14751595881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sat, 17 Jan 2026 04:54:24 +0800 Subject: [PATCH 02/20] Bump version --- clients/android | 2 +- clients/apple | 2 +- docs/changelog.md | 13 +++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/clients/android b/clients/android index 8b3433e9..39e961fc 160000 --- a/clients/android +++ b/clients/android @@ -1 +1 @@ -Subproject commit 8b3433e9ba38e1d82f3ca14002299c2a3f14b0fc +Subproject commit 39e961fcbc7f079d04297d7871932514cb8b6003 diff --git a/clients/apple b/clients/apple index 532c140f..97402ba8 160000 --- a/clients/apple +++ b/clients/apple @@ -1 +1 @@ -Subproject commit 532c140f05477e909e00541ed15c7fc7a516815e +Subproject commit 97402ba8b64d9bcc49d7d1dd73aca7ca5b46da54 diff --git a/docs/changelog.md b/docs/changelog.md index c6fd98a7..a3a25d5c 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,6 +2,19 @@ icon: material/alert-decagram --- +#### 1.12.17 + +* Update uTLS to v1.8.2 **1** +* Fixes and improvements + +**1**: + +This update fixes missing padding extension for Chrome 120+ fingerprints. + +Also, documentation has been updated with a warning about uTLS fingerprinting vulnerabilities. +uTLS is not recommended for censorship circumvention due to fundamental architectural limitations; +use NaiveProxy instead for TLS fingerprint resistance. + #### 1.12.16 * Fixes and improvements From 6e96d620fe326de8ec0fae5c35342d964441fa3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Wed, 28 Jan 2026 13:50:59 +0800 Subject: [PATCH 03/20] Minor fixes --- go.mod | 4 ++-- go.sum | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index f8e34fac..2c7ac263 100644 --- a/go.mod +++ b/go.mod @@ -27,13 +27,13 @@ require ( github.com/sagernet/gomobile v0.1.8 github.com/sagernet/gvisor v0.0.0-20250325023245-7a9c0f5725fb github.com/sagernet/quic-go v0.52.0-sing-box-mod.3 - github.com/sagernet/sing v0.7.14 + github.com/sagernet/sing v0.7.16 github.com/sagernet/sing-mux v0.3.4 github.com/sagernet/sing-quic v0.5.2 github.com/sagernet/sing-shadowsocks v0.2.8 github.com/sagernet/sing-shadowsocks2 v0.2.1 github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 - github.com/sagernet/sing-tun v0.7.3 + github.com/sagernet/sing-tun v0.7.8 github.com/sagernet/sing-vmess v0.2.7 github.com/sagernet/smux v1.5.50-sing-box-mod.1 github.com/sagernet/tailscale v1.80.3-sing-box-1.12-mod.2 diff --git a/go.sum b/go.sum index 5c1ee5a7..c3b5607f 100644 --- a/go.sum +++ b/go.sum @@ -123,8 +123,6 @@ github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ= github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0 h1:Ui+/2s5Qz0lSnDUBmEL12M5Oi/PzvFxGTNohm8ZcsmE= github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw= -github.com/metacubex/utls v1.8.3 h1:0m/yCxm3SK6kWve2lKiFb1pue1wHitJ8sQQD4Ikqde4= -github.com/metacubex/utls v1.8.3/go.mod h1:kncGGVhFaoGn5M3pFe3SXhZCzsbCJayNOH4UEqTKTko= github.com/metacubex/utls v1.8.4 h1:HmL9nUApDdWSkgUyodfwF6hSjtiwCGGdyhaSpEejKpg= github.com/metacubex/utls v1.8.4/go.mod h1:kncGGVhFaoGn5M3pFe3SXhZCzsbCJayNOH4UEqTKTko= github.com/mholt/acmez/v3 v3.1.2 h1:auob8J/0FhmdClQicvJvuDavgd5ezwLBfKuYmynhYzc= @@ -167,8 +165,8 @@ github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNen github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8= github.com/sagernet/quic-go v0.52.0-sing-box-mod.3 h1:ySqffGm82rPqI1TUPqmtHIYd12pfEGScygnOxjTL56w= github.com/sagernet/quic-go v0.52.0-sing-box-mod.3/go.mod h1:OV+V5kEBb8kJS7k29MzDu6oj9GyMc7HA07sE1tedxz4= -github.com/sagernet/sing v0.7.14 h1:5QQRDCUvYNOMyVp3LuK/hYEBAIv0VsbD3x/l9zH467s= -github.com/sagernet/sing v0.7.14/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= +github.com/sagernet/sing v0.7.16 h1:6ZnmpWJEZCWwAPj+GL7/FKEIlRaSupjtxhbpN2RjPgA= +github.com/sagernet/sing v0.7.16/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= github.com/sagernet/sing-mux v0.3.4 h1:ZQplKl8MNXutjzbMVtWvWG31fohhgOfCuUZR4dVQ8+s= github.com/sagernet/sing-mux v0.3.4/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk= github.com/sagernet/sing-quic v0.5.2 h1:I3vlfRImhr0uLwRS3b3ib70RMG9FcXtOKKUDz3eKRWc= @@ -179,8 +177,8 @@ github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnq github.com/sagernet/sing-shadowsocks2 v0.2.1/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ= github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 h1:tK+75l64tm9WvEFrYRE1t0YxoFdWQqw/h7Uhzj0vJ+w= github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA= -github.com/sagernet/sing-tun v0.7.3 h1:MFnAir+l24ElEyxdfwtY8mqvUUL9nPnL9TDYLkOmVes= -github.com/sagernet/sing-tun v0.7.3/go.mod h1:pUEjh9YHQ2gJT6Lk0TYDklh3WJy7lz+848vleGM3JPM= +github.com/sagernet/sing-tun v0.7.8 h1:v9GYPL6V1ZiViqdoRYOy1MPE9b2E6SP0YYWCIGV5fGc= +github.com/sagernet/sing-tun v0.7.8/go.mod h1:pUEjh9YHQ2gJT6Lk0TYDklh3WJy7lz+848vleGM3JPM= github.com/sagernet/sing-vmess v0.2.7 h1:2ee+9kO0xW5P4mfe6TYVWf9VtY8k1JhNysBqsiYj0sk= github.com/sagernet/sing-vmess v0.2.7/go.mod h1:5aYoOtYksAyS0NXDm0qKeTYW1yoE1bJVcv+XLcVoyJs= github.com/sagernet/smux v1.5.50-sing-box-mod.1 h1:XkJcivBC9V4wBjiGXIXZ229aZCU1hzcbp6kSkkyQ478= From 99cad72ea827af159e16ff4719e19882c8d0c7cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Wed, 28 Jan 2026 16:49:26 +0800 Subject: [PATCH 04/20] Bump version --- clients/android | 2 +- docs/changelog.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/clients/android b/clients/android index 39e961fc..17eef638 160000 --- a/clients/android +++ b/clients/android @@ -1 +1 @@ -Subproject commit 39e961fcbc7f079d04297d7871932514cb8b6003 +Subproject commit 17eef63838b2a8c803d69a108c5a75e5e9f00715 diff --git a/docs/changelog.md b/docs/changelog.md index a3a25d5c..305e0cff 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,6 +2,10 @@ icon: material/alert-decagram --- +#### 1.12.18 + +* Fixes and improvements + #### 1.12.17 * Update uTLS to v1.8.2 **1** From 58025a01f8091e114f79f2df6267d54682d3e572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Thu, 29 Jan 2026 12:07:15 +0800 Subject: [PATCH 05/20] Fix auto_redirect fallback rule --- docs/changelog.md | 8 ++++ docs/configuration/inbound/tun.md | 16 ++++++++ docs/configuration/inbound/tun.zh.md | 16 ++++++++ go.mod | 2 +- go.sum | 4 +- option/tun.go | 55 ++++++++++++++------------- protocol/tun/inbound.go | 57 +++++++++++++++------------- 7 files changed, 102 insertions(+), 56 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 305e0cff..0ffc6087 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -4,8 +4,16 @@ icon: material/alert-decagram #### 1.12.18 +* Add fallback routing rule for `auto_redirect` **1** * Fixes and improvements +**1**: + +Adds a fallback iproute2 rule checked after system default rules (32766: main, 32767: default), +ensuring traffic is routed to the sing-box table when no route is found in system tables. + +The rule index can be customized via `auto_redirect_iproute2_fallback_rule_index` (default: 32768). + #### 1.12.17 * Update uTLS to v1.8.2 **1** diff --git a/docs/configuration/inbound/tun.md b/docs/configuration/inbound/tun.md index 92313c82..79ad9f1f 100644 --- a/docs/configuration/inbound/tun.md +++ b/docs/configuration/inbound/tun.md @@ -2,6 +2,10 @@ icon: material/new-box --- +!!! quote "Changes in sing-box 1.12.18" + + :material-plus: [auto_redirect_iproute2_fallback_rule_index](#auto_redirect_iproute2_fallback_rule_index) + !!! quote "Changes in sing-box 1.12.0" :material-plus: [loopback_address](#loopback_address) @@ -63,6 +67,7 @@ icon: material/new-box "auto_redirect": true, "auto_redirect_input_mark": "0x2023", "auto_redirect_output_mark": "0x2024", + "auto_redirect_iproute2_fallback_rule_index": 32768, "loopback_address": [ "10.7.0.1" ], @@ -278,6 +283,17 @@ Connection output mark used by `auto_redirect`. `0x2024` is used by default. +#### auto_redirect_iproute2_fallback_rule_index + +!!! question "Since sing-box 1.12.18" + +Linux iproute2 fallback rule index generated by `auto_redirect`. + +This rule is checked after system default rules (32766: main, 32767: default), +routing traffic to the sing-box table only when no route is found in system tables. + +`32768` is used by default. + #### loopback_address !!! question "Since sing-box 1.12.0" diff --git a/docs/configuration/inbound/tun.zh.md b/docs/configuration/inbound/tun.zh.md index 9c053999..4ba7aed7 100644 --- a/docs/configuration/inbound/tun.zh.md +++ b/docs/configuration/inbound/tun.zh.md @@ -2,6 +2,10 @@ icon: material/new-box --- +!!! quote "sing-box 1.12.18 中的更改" + + :material-plus: [auto_redirect_iproute2_fallback_rule_index](#auto_redirect_iproute2_fallback_rule_index) + !!! quote "sing-box 1.12.0 中的更改" :material-plus: [loopback_address](#loopback_address) @@ -63,6 +67,7 @@ icon: material/new-box "auto_redirect": true, "auto_redirect_input_mark": "0x2023", "auto_redirect_output_mark": "0x2024", + "auto_redirect_iproute2_fallback_rule_index": 32768, "loopback_address": [ "10.7.0.1" ], @@ -277,6 +282,17 @@ tun 接口的 IPv6 前缀。 默认使用 `0x2024`。 +#### auto_redirect_iproute2_fallback_rule_index + +!!! question "自 sing-box 1.12.18 起" + +`auto_redirect` 生成的 iproute2 回退规则索引。 + +此规则在系统默认规则(32766: main,32767: default)之后检查, +仅当系统路由表中未找到路由时才将流量路由到 sing-box 路由表。 + +默认使用 `32768`。 + #### loopback_address !!! question "自 sing-box 1.12.0 起" diff --git a/go.mod b/go.mod index 2c7ac263..a3f2323a 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/sagernet/sing-shadowsocks v0.2.8 github.com/sagernet/sing-shadowsocks2 v0.2.1 github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 - github.com/sagernet/sing-tun v0.7.8 + github.com/sagernet/sing-tun v0.7.9 github.com/sagernet/sing-vmess v0.2.7 github.com/sagernet/smux v1.5.50-sing-box-mod.1 github.com/sagernet/tailscale v1.80.3-sing-box-1.12-mod.2 diff --git a/go.sum b/go.sum index c3b5607f..21fde21e 100644 --- a/go.sum +++ b/go.sum @@ -177,8 +177,8 @@ github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnq github.com/sagernet/sing-shadowsocks2 v0.2.1/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ= github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 h1:tK+75l64tm9WvEFrYRE1t0YxoFdWQqw/h7Uhzj0vJ+w= github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA= -github.com/sagernet/sing-tun v0.7.8 h1:v9GYPL6V1ZiViqdoRYOy1MPE9b2E6SP0YYWCIGV5fGc= -github.com/sagernet/sing-tun v0.7.8/go.mod h1:pUEjh9YHQ2gJT6Lk0TYDklh3WJy7lz+848vleGM3JPM= +github.com/sagernet/sing-tun v0.7.9 h1:kcEFA0Xa+OVcrBGnlIl33+SrW/vuB3jtOw0HQNOSJzc= +github.com/sagernet/sing-tun v0.7.9/go.mod h1:pUEjh9YHQ2gJT6Lk0TYDklh3WJy7lz+848vleGM3JPM= github.com/sagernet/sing-vmess v0.2.7 h1:2ee+9kO0xW5P4mfe6TYVWf9VtY8k1JhNysBqsiYj0sk= github.com/sagernet/sing-vmess v0.2.7/go.mod h1:5aYoOtYksAyS0NXDm0qKeTYW1yoE1bJVcv+XLcVoyJs= github.com/sagernet/smux v1.5.50-sing-box-mod.1 h1:XkJcivBC9V4wBjiGXIXZ229aZCU1hzcbp6kSkkyQ478= diff --git a/option/tun.go b/option/tun.go index 89affb23..6ff28a17 100644 --- a/option/tun.go +++ b/option/tun.go @@ -11,33 +11,34 @@ import ( ) type TunInboundOptions struct { - InterfaceName string `json:"interface_name,omitempty"` - MTU uint32 `json:"mtu,omitempty"` - Address badoption.Listable[netip.Prefix] `json:"address,omitempty"` - AutoRoute bool `json:"auto_route,omitempty"` - IPRoute2TableIndex int `json:"iproute2_table_index,omitempty"` - IPRoute2RuleIndex int `json:"iproute2_rule_index,omitempty"` - AutoRedirect bool `json:"auto_redirect,omitempty"` - AutoRedirectInputMark FwMark `json:"auto_redirect_input_mark,omitempty"` - AutoRedirectOutputMark FwMark `json:"auto_redirect_output_mark,omitempty"` - LoopbackAddress badoption.Listable[netip.Addr] `json:"loopback_address,omitempty"` - StrictRoute bool `json:"strict_route,omitempty"` - RouteAddress badoption.Listable[netip.Prefix] `json:"route_address,omitempty"` - RouteAddressSet badoption.Listable[string] `json:"route_address_set,omitempty"` - RouteExcludeAddress badoption.Listable[netip.Prefix] `json:"route_exclude_address,omitempty"` - RouteExcludeAddressSet badoption.Listable[string] `json:"route_exclude_address_set,omitempty"` - IncludeInterface badoption.Listable[string] `json:"include_interface,omitempty"` - ExcludeInterface badoption.Listable[string] `json:"exclude_interface,omitempty"` - IncludeUID badoption.Listable[uint32] `json:"include_uid,omitempty"` - IncludeUIDRange badoption.Listable[string] `json:"include_uid_range,omitempty"` - ExcludeUID badoption.Listable[uint32] `json:"exclude_uid,omitempty"` - ExcludeUIDRange badoption.Listable[string] `json:"exclude_uid_range,omitempty"` - IncludeAndroidUser badoption.Listable[int] `json:"include_android_user,omitempty"` - IncludePackage badoption.Listable[string] `json:"include_package,omitempty"` - ExcludePackage badoption.Listable[string] `json:"exclude_package,omitempty"` - UDPTimeout UDPTimeoutCompat `json:"udp_timeout,omitempty"` - Stack string `json:"stack,omitempty"` - Platform *TunPlatformOptions `json:"platform,omitempty"` + InterfaceName string `json:"interface_name,omitempty"` + MTU uint32 `json:"mtu,omitempty"` + Address badoption.Listable[netip.Prefix] `json:"address,omitempty"` + AutoRoute bool `json:"auto_route,omitempty"` + IPRoute2TableIndex int `json:"iproute2_table_index,omitempty"` + IPRoute2RuleIndex int `json:"iproute2_rule_index,omitempty"` + AutoRedirect bool `json:"auto_redirect,omitempty"` + AutoRedirectInputMark FwMark `json:"auto_redirect_input_mark,omitempty"` + AutoRedirectOutputMark FwMark `json:"auto_redirect_output_mark,omitempty"` + AutoRedirectIPRoute2FallbackRuleIndex int `json:"auto_redirect_iproute2_fallback_rule_index,omitempty"` + LoopbackAddress badoption.Listable[netip.Addr] `json:"loopback_address,omitempty"` + StrictRoute bool `json:"strict_route,omitempty"` + RouteAddress badoption.Listable[netip.Prefix] `json:"route_address,omitempty"` + RouteAddressSet badoption.Listable[string] `json:"route_address_set,omitempty"` + RouteExcludeAddress badoption.Listable[netip.Prefix] `json:"route_exclude_address,omitempty"` + RouteExcludeAddressSet badoption.Listable[string] `json:"route_exclude_address_set,omitempty"` + IncludeInterface badoption.Listable[string] `json:"include_interface,omitempty"` + ExcludeInterface badoption.Listable[string] `json:"exclude_interface,omitempty"` + IncludeUID badoption.Listable[uint32] `json:"include_uid,omitempty"` + IncludeUIDRange badoption.Listable[string] `json:"include_uid_range,omitempty"` + ExcludeUID badoption.Listable[uint32] `json:"exclude_uid,omitempty"` + ExcludeUIDRange badoption.Listable[string] `json:"exclude_uid_range,omitempty"` + IncludeAndroidUser badoption.Listable[int] `json:"include_android_user,omitempty"` + IncludePackage badoption.Listable[string] `json:"include_package,omitempty"` + ExcludePackage badoption.Listable[string] `json:"exclude_package,omitempty"` + UDPTimeout UDPTimeoutCompat `json:"udp_timeout,omitempty"` + Stack string `json:"stack,omitempty"` + Platform *TunPlatformOptions `json:"platform,omitempty"` InboundOptions // Deprecated: removed diff --git a/protocol/tun/inbound.go b/protocol/tun/inbound.go index fc69309c..ee85f80b 100644 --- a/protocol/tun/inbound.go +++ b/protocol/tun/inbound.go @@ -174,6 +174,10 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo if ruleIndex == 0 { ruleIndex = tun.DefaultIPRoute2RuleIndex } + autoRedirectFallbackRuleIndex := options.AutoRedirectIPRoute2FallbackRuleIndex + if autoRedirectFallbackRuleIndex == 0 { + autoRedirectFallbackRuleIndex = tun.DefaultIPRoute2AutoRedirectFallbackRuleIndex + } inputMark := uint32(options.AutoRedirectInputMark) if inputMark == 0 { inputMark = tun.DefaultAutoRedirectInputMark @@ -192,32 +196,33 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo logger: logger, inboundOptions: options.InboundOptions, tunOptions: tun.Options{ - Name: options.InterfaceName, - MTU: tunMTU, - GSO: enableGSO, - Inet4Address: inet4Address, - Inet6Address: inet6Address, - AutoRoute: options.AutoRoute, - IPRoute2TableIndex: tableIndex, - IPRoute2RuleIndex: ruleIndex, - AutoRedirectInputMark: inputMark, - AutoRedirectOutputMark: outputMark, - Inet4LoopbackAddress: common.Filter(options.LoopbackAddress, netip.Addr.Is4), - Inet6LoopbackAddress: common.Filter(options.LoopbackAddress, netip.Addr.Is6), - StrictRoute: options.StrictRoute, - IncludeInterface: options.IncludeInterface, - ExcludeInterface: options.ExcludeInterface, - Inet4RouteAddress: inet4RouteAddress, - Inet6RouteAddress: inet6RouteAddress, - Inet4RouteExcludeAddress: inet4RouteExcludeAddress, - Inet6RouteExcludeAddress: inet6RouteExcludeAddress, - IncludeUID: includeUID, - ExcludeUID: excludeUID, - IncludeAndroidUser: options.IncludeAndroidUser, - IncludePackage: options.IncludePackage, - ExcludePackage: options.ExcludePackage, - InterfaceMonitor: networkManager.InterfaceMonitor(), - EXP_MultiPendingPackets: multiPendingPackets, + Name: options.InterfaceName, + MTU: tunMTU, + GSO: enableGSO, + Inet4Address: inet4Address, + Inet6Address: inet6Address, + AutoRoute: options.AutoRoute, + IPRoute2TableIndex: tableIndex, + IPRoute2RuleIndex: ruleIndex, + IPRoute2AutoRedirectFallbackRuleIndex: autoRedirectFallbackRuleIndex, + AutoRedirectInputMark: inputMark, + AutoRedirectOutputMark: outputMark, + Inet4LoopbackAddress: common.Filter(options.LoopbackAddress, netip.Addr.Is4), + Inet6LoopbackAddress: common.Filter(options.LoopbackAddress, netip.Addr.Is6), + StrictRoute: options.StrictRoute, + IncludeInterface: options.IncludeInterface, + ExcludeInterface: options.ExcludeInterface, + Inet4RouteAddress: inet4RouteAddress, + Inet6RouteAddress: inet6RouteAddress, + Inet4RouteExcludeAddress: inet4RouteExcludeAddress, + Inet6RouteExcludeAddress: inet6RouteExcludeAddress, + IncludeUID: includeUID, + ExcludeUID: excludeUID, + IncludeAndroidUser: options.IncludeAndroidUser, + IncludePackage: options.IncludePackage, + ExcludePackage: options.ExcludePackage, + InterfaceMonitor: networkManager.InterfaceMonitor(), + EXP_MultiPendingPackets: multiPendingPackets, }, udpTimeout: udpTimeout, stack: options.Stack, From d9eb8f3ab60394f482c457abb044eca90ff32b42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sun, 1 Feb 2026 10:11:15 +0800 Subject: [PATCH 06/20] Fix varbin serialization --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a3f2323a..dbfbdac5 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/sagernet/gomobile v0.1.8 github.com/sagernet/gvisor v0.0.0-20250325023245-7a9c0f5725fb github.com/sagernet/quic-go v0.52.0-sing-box-mod.3 - github.com/sagernet/sing v0.7.16 + github.com/sagernet/sing v0.7.18 github.com/sagernet/sing-mux v0.3.4 github.com/sagernet/sing-quic v0.5.2 github.com/sagernet/sing-shadowsocks v0.2.8 diff --git a/go.sum b/go.sum index 21fde21e..15b870bb 100644 --- a/go.sum +++ b/go.sum @@ -165,8 +165,8 @@ github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNen github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8= github.com/sagernet/quic-go v0.52.0-sing-box-mod.3 h1:ySqffGm82rPqI1TUPqmtHIYd12pfEGScygnOxjTL56w= github.com/sagernet/quic-go v0.52.0-sing-box-mod.3/go.mod h1:OV+V5kEBb8kJS7k29MzDu6oj9GyMc7HA07sE1tedxz4= -github.com/sagernet/sing v0.7.16 h1:6ZnmpWJEZCWwAPj+GL7/FKEIlRaSupjtxhbpN2RjPgA= -github.com/sagernet/sing v0.7.16/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= +github.com/sagernet/sing v0.7.18 h1:iZHkaru1/MoHugx3G+9S3WG4owMewKO/KvieE2Pzk4E= +github.com/sagernet/sing v0.7.18/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= github.com/sagernet/sing-mux v0.3.4 h1:ZQplKl8MNXutjzbMVtWvWG31fohhgOfCuUZR4dVQ8+s= github.com/sagernet/sing-mux v0.3.4/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk= github.com/sagernet/sing-quic v0.5.2 h1:I3vlfRImhr0uLwRS3b3ib70RMG9FcXtOKKUDz3eKRWc= From 00b2c042ee8849767fb5ed056c44b85c9b8a0adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sun, 1 Feb 2026 10:17:34 +0800 Subject: [PATCH 07/20] Disable rp filter atomically --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index dbfbdac5..92befc9a 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/sagernet/sing-shadowsocks v0.2.8 github.com/sagernet/sing-shadowsocks2 v0.2.1 github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 - github.com/sagernet/sing-tun v0.7.9 + github.com/sagernet/sing-tun v0.7.10 github.com/sagernet/sing-vmess v0.2.7 github.com/sagernet/smux v1.5.50-sing-box-mod.1 github.com/sagernet/tailscale v1.80.3-sing-box-1.12-mod.2 diff --git a/go.sum b/go.sum index 15b870bb..2cc4a010 100644 --- a/go.sum +++ b/go.sum @@ -177,8 +177,8 @@ github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnq github.com/sagernet/sing-shadowsocks2 v0.2.1/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ= github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 h1:tK+75l64tm9WvEFrYRE1t0YxoFdWQqw/h7Uhzj0vJ+w= github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA= -github.com/sagernet/sing-tun v0.7.9 h1:kcEFA0Xa+OVcrBGnlIl33+SrW/vuB3jtOw0HQNOSJzc= -github.com/sagernet/sing-tun v0.7.9/go.mod h1:pUEjh9YHQ2gJT6Lk0TYDklh3WJy7lz+848vleGM3JPM= +github.com/sagernet/sing-tun v0.7.10 h1:lLBaS9uL0mK/FCGDe3N4oKQxjMGfmv3u2/6jKtmq4Pw= +github.com/sagernet/sing-tun v0.7.10/go.mod h1:pUEjh9YHQ2gJT6Lk0TYDklh3WJy7lz+848vleGM3JPM= github.com/sagernet/sing-vmess v0.2.7 h1:2ee+9kO0xW5P4mfe6TYVWf9VtY8k1JhNysBqsiYj0sk= github.com/sagernet/sing-vmess v0.2.7/go.mod h1:5aYoOtYksAyS0NXDm0qKeTYW1yoE1bJVcv+XLcVoyJs= github.com/sagernet/smux v1.5.50-sing-box-mod.1 h1:XkJcivBC9V4wBjiGXIXZ229aZCU1hzcbp6kSkkyQ478= From 69bebbda82f0e6f04d128e320de4585b723bee52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sun, 1 Feb 2026 10:19:35 +0800 Subject: [PATCH 08/20] Bump version --- clients/android | 2 +- docs/changelog.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/clients/android b/clients/android index 17eef638..6d42332a 160000 --- a/clients/android +++ b/clients/android @@ -1 +1 @@ -Subproject commit 17eef63838b2a8c803d69a108c5a75e5e9f00715 +Subproject commit 6d42332aaf360fe421312e61bb51a9110cc9b2ba diff --git a/docs/changelog.md b/docs/changelog.md index 0ffc6087..04bcc9d8 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,6 +2,10 @@ icon: material/alert-decagram --- +#### 1.12.19 + +* Fixes and improvements + #### 1.12.18 * Add fallback routing rule for `auto_redirect` **1** From f2639a58292f22e54447fce5ddfef1fdc0388af7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 2 Feb 2026 14:13:09 +0800 Subject: [PATCH 09/20] Fix random iproute2 table index was incorrectly removed --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 92befc9a..50c98ddb 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/sagernet/sing-shadowsocks v0.2.8 github.com/sagernet/sing-shadowsocks2 v0.2.1 github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 - github.com/sagernet/sing-tun v0.7.10 + github.com/sagernet/sing-tun v0.7.11 github.com/sagernet/sing-vmess v0.2.7 github.com/sagernet/smux v1.5.50-sing-box-mod.1 github.com/sagernet/tailscale v1.80.3-sing-box-1.12-mod.2 diff --git a/go.sum b/go.sum index 2cc4a010..bfb979af 100644 --- a/go.sum +++ b/go.sum @@ -177,8 +177,8 @@ github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnq github.com/sagernet/sing-shadowsocks2 v0.2.1/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ= github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 h1:tK+75l64tm9WvEFrYRE1t0YxoFdWQqw/h7Uhzj0vJ+w= github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA= -github.com/sagernet/sing-tun v0.7.10 h1:lLBaS9uL0mK/FCGDe3N4oKQxjMGfmv3u2/6jKtmq4Pw= -github.com/sagernet/sing-tun v0.7.10/go.mod h1:pUEjh9YHQ2gJT6Lk0TYDklh3WJy7lz+848vleGM3JPM= +github.com/sagernet/sing-tun v0.7.11 h1:qB7jy8JKqXg73fYBsDkBSy4ulRSbLrFut0e+y+QPhqU= +github.com/sagernet/sing-tun v0.7.11/go.mod h1:pUEjh9YHQ2gJT6Lk0TYDklh3WJy7lz+848vleGM3JPM= github.com/sagernet/sing-vmess v0.2.7 h1:2ee+9kO0xW5P4mfe6TYVWf9VtY8k1JhNysBqsiYj0sk= github.com/sagernet/sing-vmess v0.2.7/go.mod h1:5aYoOtYksAyS0NXDm0qKeTYW1yoE1bJVcv+XLcVoyJs= github.com/sagernet/smux v1.5.50-sing-box-mod.1 h1:XkJcivBC9V4wBjiGXIXZ229aZCU1hzcbp6kSkkyQ478= From 3ba30e3f006bf0d90335d29cf07d09845a454073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 2 Feb 2026 17:29:21 +0800 Subject: [PATCH 10/20] Fix route_address_set duplicated IP sets causing route creation failure The FlatMap calls pre-populated routeAddressSet and routeExcludeAddressSet before the for-loops which appended the same IP sets again, doubling every entry. On Windows this caused CreateIpForwardEntry2 to return ERROR_OBJECT_ALREADY_EXISTS. Fixes #3725 --- protocol/tun/inbound.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/protocol/tun/inbound.go b/protocol/tun/inbound.go index ee85f80b..bfa19eaf 100644 --- a/protocol/tun/inbound.go +++ b/protocol/tun/inbound.go @@ -324,7 +324,6 @@ func (t *Inbound) Start(stage adapter.StartStage) error { t.tunOptions.Name = tun.CalculateInterfaceName("") } if t.platformInterface == nil { - t.routeAddressSet = common.FlatMap(t.routeRuleSet, adapter.RuleSet.ExtractIPSet) for _, routeRuleSet := range t.routeRuleSet { ipSets := routeRuleSet.ExtractIPSet() if len(ipSets) == 0 { @@ -336,7 +335,6 @@ func (t *Inbound) Start(stage adapter.StartStage) error { t.routeRuleSetCallback = append(t.routeRuleSetCallback, routeRuleSet.RegisterCallback(t.updateRouteAddressSet)) } } - t.routeExcludeAddressSet = common.FlatMap(t.routeExcludeRuleSet, adapter.RuleSet.ExtractIPSet) for _, routeExcludeRuleSet := range t.routeExcludeRuleSet { ipSets := routeExcludeRuleSet.ExtractIPSet() if len(ipSets) == 0 { From 2f8e656522b00a2518aed6b4e0feb020a8ac91b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Thu, 5 Feb 2026 17:12:15 +0800 Subject: [PATCH 11/20] Update Go to 1.25.7 --- .github/setup_go_for_windows7.sh | 2 +- .github/workflows/build.yml | 10 +++++----- .github/workflows/linux.yml | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/setup_go_for_windows7.sh b/.github/setup_go_for_windows7.sh index de440afa..fe31b944 100755 --- a/.github/setup_go_for_windows7.sh +++ b/.github/setup_go_for_windows7.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -VERSION="1.25.6" +VERSION="1.25.7" mkdir -p $HOME/go cd $HOME/go diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5ef5ae20..8011bb5b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,7 +46,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: ^1.25.6 + go-version: ^1.25.7 - name: Check input version if: github.event_name == 'workflow_dispatch' run: |- @@ -110,7 +110,7 @@ jobs: if: ${{ ! (matrix.legacy_win7 || matrix.legacy_go124) }} uses: actions/setup-go@v5 with: - go-version: ^1.25.6 + go-version: ^1.25.7 - name: Setup Go 1.24 if: matrix.legacy_go124 uses: actions/setup-go@v5 @@ -300,7 +300,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: ^1.25.6 + go-version: ^1.25.7 - name: Setup Android NDK id: setup-ndk uses: nttld/setup-ndk@v1 @@ -380,7 +380,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: ^1.25.6 + go-version: ^1.25.7 - name: Setup Android NDK id: setup-ndk uses: nttld/setup-ndk@v1 @@ -479,7 +479,7 @@ jobs: if: matrix.if uses: actions/setup-go@v5 with: - go-version: ^1.25.6 + go-version: ^1.25.7 - name: Set tag if: matrix.if run: |- diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 0f009697..da7bec07 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -30,7 +30,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: ^1.25.6 + go-version: ^1.25.7 - name: Check input version if: github.event_name == 'workflow_dispatch' run: |- @@ -71,7 +71,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: ^1.25.6 + go-version: ^1.25.7 - name: Setup Android NDK if: matrix.os == 'android' uses: nttld/setup-ndk@v1 From 0f3774e50116afef049c6d7ce33a50574071529e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Wed, 4 Feb 2026 14:06:00 +0800 Subject: [PATCH 12/20] Bump version --- clients/android | 2 +- docs/changelog.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/clients/android b/clients/android index 6d42332a..661fc3cc 160000 --- a/clients/android +++ b/clients/android @@ -1 +1 @@ -Subproject commit 6d42332aaf360fe421312e61bb51a9110cc9b2ba +Subproject commit 661fc3cc2a0af8ce8669722810482f34091a610e diff --git a/docs/changelog.md b/docs/changelog.md index 04bcc9d8..04a8450f 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,6 +2,10 @@ icon: material/alert-decagram --- +#### 1.12.20 + +* Fixes and improvements + #### 1.12.19 * Fixes and improvements From e7a9c90213a64b3d71cf6b2f312f930f48a8065f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Fri, 6 Feb 2026 22:28:30 +0800 Subject: [PATCH 13/20] Fix DNS cache lock goroutine leak The cache deduplication in Client.Exchange uses a channel-based lock per DNS question. Waiting goroutines blocked on <-cond without context awareness, causing them to accumulate indefinitely when the owning goroutine's transport call stalls. Add select on ctx.Done() so waiters respect context cancellation and timeouts. --- dns/client.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/dns/client.go b/dns/client.go index 939ca48c..2982d11c 100644 --- a/dns/client.go +++ b/dns/client.go @@ -144,7 +144,11 @@ func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, m if c.cache != nil { cond, loaded := c.cacheLock.LoadOrStore(question, make(chan struct{})) if loaded { - <-cond + select { + case <-cond: + case <-ctx.Done(): + return nil, ctx.Err() + } } else { defer func() { c.cacheLock.Delete(question) @@ -154,7 +158,11 @@ func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, m } else if c.transportCache != nil { cond, loaded := c.transportCacheLock.LoadOrStore(question, make(chan struct{})) if loaded { - <-cond + select { + case <-cond: + case <-ctx.Done(): + return nil, ctx.Err() + } } else { defer func() { c.transportCacheLock.Delete(question) From 736a7368c62a4f33eec98f7704456faea3f6fadd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 9 Feb 2026 13:46:53 +0800 Subject: [PATCH 14/20] Fix naive padding --- protocol/naive/inbound_conn.go | 1 + 1 file changed, 1 insertion(+) diff --git a/protocol/naive/inbound_conn.go b/protocol/naive/inbound_conn.go index 1dbb2bd8..0711b637 100644 --- a/protocol/naive/inbound_conn.go +++ b/protocol/naive/inbound_conn.go @@ -95,6 +95,7 @@ func (p *paddingConn) writeWithPadding(writer io.Writer, data []byte) (n int, er binary.BigEndian.PutUint16(header, uint16(len(data))) header[2] = byte(paddingSize) common.Must1(buffer.Write(data)) + buffer.Extend(paddingSize) _, err = writer.Write(buffer.Bytes()) if err == nil { n = len(data) From 534128bba9bdd46b44e15b841e8935e58414c865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 9 Feb 2026 13:55:09 +0800 Subject: [PATCH 15/20] tuic: Fix udp context --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 50c98ddb..236c1488 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/sagernet/quic-go v0.52.0-sing-box-mod.3 github.com/sagernet/sing v0.7.18 github.com/sagernet/sing-mux v0.3.4 - github.com/sagernet/sing-quic v0.5.2 + github.com/sagernet/sing-quic v0.5.3 github.com/sagernet/sing-shadowsocks v0.2.8 github.com/sagernet/sing-shadowsocks2 v0.2.1 github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 diff --git a/go.sum b/go.sum index bfb979af..3e8f9e4d 100644 --- a/go.sum +++ b/go.sum @@ -169,8 +169,8 @@ github.com/sagernet/sing v0.7.18 h1:iZHkaru1/MoHugx3G+9S3WG4owMewKO/KvieE2Pzk4E= github.com/sagernet/sing v0.7.18/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= github.com/sagernet/sing-mux v0.3.4 h1:ZQplKl8MNXutjzbMVtWvWG31fohhgOfCuUZR4dVQ8+s= github.com/sagernet/sing-mux v0.3.4/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk= -github.com/sagernet/sing-quic v0.5.2 h1:I3vlfRImhr0uLwRS3b3ib70RMG9FcXtOKKUDz3eKRWc= -github.com/sagernet/sing-quic v0.5.2/go.mod h1:evP1e++ZG8TJHVV5HudXV4vWeYzGfCdF4HwSJZcdqkI= +github.com/sagernet/sing-quic v0.5.3 h1:K937DKJN98xqyztijRkLJqbBfyV4rEZcYxFyP3EBikU= +github.com/sagernet/sing-quic v0.5.3/go.mod h1:evP1e++ZG8TJHVV5HudXV4vWeYzGfCdF4HwSJZcdqkI= github.com/sagernet/sing-shadowsocks v0.2.8 h1:PURj5PRoAkqeHh2ZW205RWzN9E9RtKCVCzByXruQWfE= github.com/sagernet/sing-shadowsocks v0.2.8/go.mod h1:lo7TWEMDcN5/h5B8S0ew+r78ZODn6SwVaFhvB6H+PTI= github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnqqs2gQ2/Qioo= From d18d2b352abba20ce1fe2ccf3cc7ba17697b3a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 9 Feb 2026 13:55:44 +0800 Subject: [PATCH 16/20] Bump version --- clients/android | 2 +- docs/changelog.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/clients/android b/clients/android index 661fc3cc..5e1339b9 160000 --- a/clients/android +++ b/clients/android @@ -1 +1 @@ -Subproject commit 661fc3cc2a0af8ce8669722810482f34091a610e +Subproject commit 5e1339b933ffda873cb84e1637fd3286396f28f2 diff --git a/docs/changelog.md b/docs/changelog.md index 04a8450f..923b19dc 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,6 +2,10 @@ icon: material/alert-decagram --- +#### 1.12.21 + +* Fixes and improvements + #### 1.12.20 * Fixes and improvements From 6fc511f56e0f02878778d5f97f50e2b982ed2dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Fri, 13 Feb 2026 00:50:08 +0800 Subject: [PATCH 17/20] wireguard: Fix missing fallback for gso --- transport/wireguard/device_system.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transport/wireguard/device_system.go b/transport/wireguard/device_system.go index fa54f332..d2a4098c 100644 --- a/transport/wireguard/device_system.go +++ b/transport/wireguard/device_system.go @@ -88,7 +88,7 @@ func (w *systemDevice) Start() error { w.options.Logger.Info("started at ", w.options.Name) w.device = tunInterface batchTUN, isBatchTUN := tunInterface.(tun.LinuxTUN) - if isBatchTUN { + if isBatchTUN && batchTUN.BatchSize() > 1 { w.batchDevice = batchTUN } w.events <- wgTun.EventUp From 4d7f99310c69db8442feae115f19f00a152129b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sat, 14 Feb 2026 01:59:53 +0800 Subject: [PATCH 18/20] Fix matching rule-set invert --- route/rule/rule_abstract.go | 4 +- route/rule/rule_abstract_test.go | 157 +++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 route/rule/rule_abstract_test.go diff --git a/route/rule/rule_abstract.go b/route/rule/rule_abstract.go index 5be215e0..45d5b893 100644 --- a/route/rule/rule_abstract.go +++ b/route/rule/rule_abstract.go @@ -107,9 +107,7 @@ func (r *abstractDefaultRule) Match(metadata *adapter.InboundContext) bool { } for _, item := range r.items { - if _, isRuleSet := item.(*RuleSetItem); !isRuleSet { - metadata.DidMatch = true - } + metadata.DidMatch = true if !item.Match(metadata) { return r.invert } diff --git a/route/rule/rule_abstract_test.go b/route/rule/rule_abstract_test.go new file mode 100644 index 00000000..2d2e8ba8 --- /dev/null +++ b/route/rule/rule_abstract_test.go @@ -0,0 +1,157 @@ +package rule + +import ( + "context" + "testing" + + "github.com/sagernet/sing-box/adapter" + C "github.com/sagernet/sing-box/constant" + "github.com/sagernet/sing/common/x/list" + + "github.com/stretchr/testify/require" + "go4.org/netipx" +) + +type fakeRuleSet struct { + matched bool +} + +func (f *fakeRuleSet) Name() string { + return "fake-rule-set" +} + +func (f *fakeRuleSet) StartContext(context.Context, *adapter.HTTPStartContext) error { + return nil +} + +func (f *fakeRuleSet) PostStart() error { + return nil +} + +func (f *fakeRuleSet) Metadata() adapter.RuleSetMetadata { + return adapter.RuleSetMetadata{} +} + +func (f *fakeRuleSet) ExtractIPSet() []*netipx.IPSet { + return nil +} + +func (f *fakeRuleSet) IncRef() {} + +func (f *fakeRuleSet) DecRef() {} + +func (f *fakeRuleSet) Cleanup() {} + +func (f *fakeRuleSet) RegisterCallback(adapter.RuleSetUpdateCallback) *list.Element[adapter.RuleSetUpdateCallback] { + return nil +} + +func (f *fakeRuleSet) UnregisterCallback(*list.Element[adapter.RuleSetUpdateCallback]) {} + +func (f *fakeRuleSet) Close() error { + return nil +} + +func (f *fakeRuleSet) Match(*adapter.InboundContext) bool { + return f.matched +} + +func (f *fakeRuleSet) String() string { + return "fake-rule-set" +} + +type fakeRuleItem struct { + matched bool +} + +func (f *fakeRuleItem) Match(*adapter.InboundContext) bool { + return f.matched +} + +func (f *fakeRuleItem) String() string { + return "fake-rule-item" +} + +func newRuleSetOnlyRule(ruleSetMatched bool, invert bool) *DefaultRule { + ruleSetItem := &RuleSetItem{ + setList: []adapter.RuleSet{&fakeRuleSet{matched: ruleSetMatched}}, + } + return &DefaultRule{ + abstractDefaultRule: abstractDefaultRule{ + items: []RuleItem{ruleSetItem}, + allItems: []RuleItem{ruleSetItem}, + invert: invert, + }, + } +} + +func newSingleItemRule(matched bool) *DefaultRule { + item := &fakeRuleItem{matched: matched} + return &DefaultRule{ + abstractDefaultRule: abstractDefaultRule{ + items: []RuleItem{item}, + allItems: []RuleItem{item}, + }, + } +} + +func TestAbstractDefaultRule_RuleSetOnly_InvertFalse(t *testing.T) { + t.Parallel() + require.True(t, newRuleSetOnlyRule(true, false).Match(&adapter.InboundContext{})) + require.False(t, newRuleSetOnlyRule(false, false).Match(&adapter.InboundContext{})) +} + +func TestAbstractDefaultRule_RuleSetOnly_InvertTrue(t *testing.T) { + t.Parallel() + require.False(t, newRuleSetOnlyRule(true, true).Match(&adapter.InboundContext{})) + require.True(t, newRuleSetOnlyRule(false, true).Match(&adapter.InboundContext{})) +} + +func TestAbstractLogicalRule_And_WithRuleSetInvert(t *testing.T) { + t.Parallel() + testCases := []struct { + name string + aMatched bool + ruleSetBMatch bool + expected bool + }{ + { + name: "A true B true", + aMatched: true, + ruleSetBMatch: true, + expected: false, + }, + { + name: "A true B false", + aMatched: true, + ruleSetBMatch: false, + expected: true, + }, + { + name: "A false B true", + aMatched: false, + ruleSetBMatch: true, + expected: false, + }, + { + name: "A false B false", + aMatched: false, + ruleSetBMatch: false, + expected: false, + }, + } + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + logicalRule := &abstractLogicalRule{ + mode: C.LogicalTypeAnd, + rules: []adapter.HeadlessRule{ + newSingleItemRule(testCase.aMatched), + newRuleSetOnlyRule(testCase.ruleSetBMatch, true), + }, + } + require.Equal(t, testCase.expected, logicalRule.Match(&adapter.InboundContext{})) + }) + } +} From 1c4a01ee90564c3559988d75402474817cb4d14a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sun, 15 Feb 2026 19:19:47 +0800 Subject: [PATCH 19/20] Fix matching multi predefined --- dns/router.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dns/router.go b/dns/router.go index 8de1f6a9..5d028059 100644 --- a/dns/router.go +++ b/dns/router.go @@ -378,9 +378,11 @@ func (r *Router) Lookup(ctx context.Context, domain string, options adapter.DNSQ case *R.RuleActionReject: return nil, &R.RejectedError{Cause: action.Error(ctx)} case *R.RuleActionPredefined: + responseAddrs = nil if action.Rcode != mDNS.RcodeSuccess { err = RcodeError(action.Rcode) } else { + err = nil for _, answer := range action.Answer { switch record := answer.(type) { case *mDNS.A: From f63091d14d8984d53dc9a5563cb72af978b9779e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sun, 15 Feb 2026 20:39:25 +0800 Subject: [PATCH 20/20] Bump version --- clients/android | 2 +- docs/changelog.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/clients/android b/clients/android index 5e1339b9..eb872169 160000 --- a/clients/android +++ b/clients/android @@ -1 +1 @@ -Subproject commit 5e1339b933ffda873cb84e1637fd3286396f28f2 +Subproject commit eb87216961321de1802e1355c470242f2ed5faa8 diff --git a/docs/changelog.md b/docs/changelog.md index 923b19dc..ebe0db85 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,6 +2,10 @@ icon: material/alert-decagram --- +#### 1.12.22 + +* Fixes and improvements + #### 1.12.21 * Fixes and improvements