Compare commits

..
Author SHA1 Message Date
世界 5d85fa16ce documentation: Update changelog 2023-08-09 10:38:42 +08:00
世界 3442c7a692 Add TCP MultiPath support 2023-08-09 10:38:40 +08:00
世界 c485c11a0c platform: Enable Clash API support by default 2023-08-09 10:38:39 +08:00
世界 3e43a676a6 Save fakeip metadata immediately 2023-08-09 10:38:39 +08:00
世界 5acc40d72f Pause recurring tasks when no network 2023-08-09 10:38:38 +08:00
世界 2d0aa96cbe documentation: Add TUIC 2023-08-09 10:38:38 +08:00
世界 a7e16ee502 Add TUIC protocol 2023-08-09 10:38:38 +08:00
世界 56974ff465 Update quic-go 2023-08-09 10:38:29 +08:00
世界 6de6804212 Update quic-go to v0.37.3 2023-08-08 20:08:25 +08:00
世界 3e6d34adea Update dependencies 2023-08-08 20:08:16 +08:00
世界 6ec8ff79b5 Fix network monitor 2023-08-07 22:37:17 +08:00
53 changed files with 679 additions and 617 deletions
+52 -59
View File
@@ -1,77 +1,70 @@
name: Bug report
description: "Report sing-box bug"
name: Bug Report
description: "Create a report to help us improve."
body:
- type: dropdown
- type: checkboxes
id: terms
attributes:
label: Operating system
description: Operating system type
label: Welcome
options:
- iOS
- macOS
- Apple tvOS
- Android
- Windows
- Linux
- Others
validations:
required: true
- type: input
attributes:
label: System version
description: Please provide the operating system version
validations:
required: true
- type: dropdown
attributes:
label: Installation type
description: Please provide the sing-box installation type
options:
- Original sing-box Command Line
- sing-box for iOS Graphical Client
- sing-box for macOS Graphical Client
- sing-box for Apple tvOS Graphical Client
- sing-box for Android Graphical Client
- Third-party graphical clients that advertise themselves as using sing-box (Windows)
- Third-party graphical clients that advertise themselves as using sing-box (Android)
- Others
validations:
required: true
- type: input
attributes:
description: Graphical client version
label: If you are using a graphical client, please provide the version of the client.
- label: Yes, I'm using the latest major release. Only such installations are supported.
required: true
- label: Yes, I'm using the latest Golang release. Only such installations are supported.
required: true
- label: Yes, I've searched similar issues on GitHub and didn't find any.
required: true
- label: Yes, I've included all information below (version, **FULL** config, **FULL** log, etc).
required: true
- type: textarea
id: problem
attributes:
label: Version
description: If you are using the original command line program, please provide the output of the `sing-box version` command.
label: Description of the problem
placeholder: Your problem description
validations:
required: true
- type: textarea
id: version
attributes:
label: Version of sing-box
value: |-
<details>
```console
# Replace this line with the output
$ sing-box version
# Paste output here
```
</details>
- type: textarea
attributes:
label: Description
description: Please provide a detailed description of the error.
validations:
required: true
- type: textarea
id: config
attributes:
label: Reproduction
description: Please provide the steps to reproduce the error, including the configuration files and procedures that can locally (not dependent on the remote server) reproduce the error using the original command line program of sing-box.
validations:
required: true
- type: textarea
attributes:
label: Logs
description: |-
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 the Android client, please check the `/sdcard/Android/data/io.nekohasekai.sfa/files/stderr.log` file for crash logs.
label: Server and client configuration file
value: |-
<details>
```console
# Replace this line with logs
# paste json here
```
</details>
</details>
validations:
required: true
- type: textarea
id: log
attributes:
label: Server and client log file
value: |-
<details>
```console
# paste log here
```
</details>
validations:
required: true
-77
View File
@@ -1,77 +0,0 @@
name: 错误反馈
description: "提交 sing-box 漏洞"
body:
- type: dropdown
attributes:
label: 操作系统
description: 请提供操作系统类型
options:
- iOS
- macOS
- Apple tvOS
- Android
- Windows
- Linux
- 其他
validations:
required: true
- type: input
attributes:
label: 系统版本
description: 请提供操作系统版本
validations:
required: true
- type: dropdown
attributes:
label: 安装类型
description: 请提供该 sing-box 安装类型
options:
- sing-box 原始命令行程序
- sing-box for iOS 图形客户端程序
- sing-box for macOS 图形客户端程序
- sing-box for Apple tvOS 图形客户端程序
- sing-box for Android 图形客户端程序
- 宣传使用 sing-box 的第三方图形客户端程序 (Windows)
- 宣传使用 sing-box 的第三方图形客户端程序 (Android)
- 其他
validations:
required: true
- type: input
attributes:
description: 图形客户端版本
label: 如果您使用图形客户端程序,请提供该程序版本。
- type: textarea
attributes:
label: 版本
description: 如果您使用原始命令行程序,请提供 `sing-box version` 命令的输出。
value: |-
<details>
```console
# 使用输出内容覆盖此行
```
</details>
- type: textarea
attributes:
label: 描述
description: 请提供错误的详细描述。
validations:
required: true
- type: textarea
attributes:
label: 重现方式
description: 请提供重现错误的步骤,必须包括可以在本地(不依赖与远程服务器)使用 sing-box 原始命令行程序重现错误的配置文件与流程。
validations:
required: true
- type: textarea
attributes:
label: 日志
description: |-
如果您遭遇图形界面应用程序崩溃,请提供崩溃日志。
对于 Apple 平台图形客户端程序,请检查 `Settings - View Service Log` 以导出崩溃日志。
对于 Android 图形客户端程序,请检查 `/sdcard/Android/data/io.nekohasekai.sfa/files/stderr.log` 文件以导出崩溃日志。
value: |-
<details>
```console
# 使用日志内容覆盖此行
```
</details>
+1 -21
View File
@@ -62,27 +62,7 @@ jobs:
~/go/pkg/mod
key: go118-${{ hashFiles('**/go.sum') }}
- name: Run Test
run: make ci_build_go118
build_go120:
name: Debug build (Go 1.20)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: 1.20.7
- name: Cache go module
uses: actions/cache@v3
with:
path: |
~/go/pkg/mod
key: go118-${{ hashFiles('**/go.sum') }}
- name: Run Test
run: make ci_build
run: make
cross:
strategy:
matrix:
+20
View File
@@ -0,0 +1,20 @@
name: Generate Documents
on:
push:
branches:
- dev
paths:
- docs/**
- .github/workflows/mkdocs.yml
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.x
- run: |
pip install mkdocs-material=="9.*" mkdocs-static-i18n=="0.53"
- run: |
mkdocs gh-deploy -m "{sha}" --force --ignore-version --no-history
+1 -1
View File
@@ -1,4 +1,4 @@
FROM golang:1.21-alpine AS builder
FROM golang:1.20-alpine AS builder
LABEL maintainer="nekohasekai <contact-git@sekai.icu>"
COPY . /go/src/github.com/sagernet/sing-box
WORKDIR /go/src/github.com/sagernet/sing-box
+2 -12
View File
@@ -1,30 +1,20 @@
NAME = sing-box
COMMIT = $(shell git rev-parse --short HEAD)
TAGS_GO118 = with_gvisor,with_dhcp,with_wireguard,with_utls,with_reality_server,with_clash_api
TAGS_GO120 ?= with_quic
TAGS ?= with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_reality_server,with_clash_api
TAGS_TEST ?= with_gvisor,with_quic,with_wireguard,with_grpc,with_ech,with_utls,with_reality_server,with_shadowsocksr
GOHOSTOS = $(shell go env GOHOSTOS)
GOHOSTARCH = $(shell go env GOHOSTARCH)
VERSION=$(shell CGO_ENABLED=0 GOOS=$(GOHOSTOS) GOARCH=$(GOHOSTARCH) go run ./cmd/internal/read_tag)
PARAMS = -v -trimpath -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=$(VERSION)' -s -w -buildid="
MAIN_PARAMS = $(PARAMS) -tags "$(TAGS_GO118),$(TAGS_GO120)"
PARAMS = -v -trimpath -tags "$(TAGS)" -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=$(VERSION)' -s -w -buildid="
MAIN = ./cmd/sing-box
PREFIX ?= $(shell go env GOPATH)
.PHONY: test release
build:
go build $(MAIN_PARAMS) $(MAIN)
ci_build_go118:
go build $(PARAMS) $(MAIN)
go build $(PARAMS) -tags "$(TAGS_GO118)" $(MAIN)
ci_build:
go build $(PARAMS) $(MAIN)
go build $(MAIN_PARAMS) $(MAIN)
install:
go build -o $(PREFIX)/bin/$(NAME) $(PARAMS) $(MAIN)
-2
View File
@@ -23,8 +23,6 @@ type ClashServer interface {
type ClashCacheFile interface {
LoadSelected(group string) string
StoreSelected(group string, selected string) error
LoadGroupExpand(group string) (isExpand bool, loaded bool)
StoreGroupExpand(group string, expand bool) error
FakeIPStorage
}
+2 -2
View File
@@ -145,7 +145,7 @@ func New(options Options) (*Box, error) {
preServices := make(map[string]adapter.Service)
postServices := make(map[string]adapter.Service)
if needClashAPI {
clashServer, err := experimental.NewClashServer(ctx, router, logFactory.(log.ObservableFactory), common.PtrValueOrDefault(experimentalOptions.ClashAPI))
clashServer, err := experimental.NewClashServer(ctx, router, logFactory.(log.ObservableFactory), common.PtrValueOrDefault(options.Experimental.ClashAPI))
if err != nil {
return nil, E.Cause(err, "create clash api server")
}
@@ -153,7 +153,7 @@ func New(options Options) (*Box, error) {
preServices["clash api"] = clashServer
}
if needV2RayAPI {
v2rayServer, err := experimental.NewV2RayServer(logFactory.NewLogger("v2ray-api"), common.PtrValueOrDefault(experimentalOptions.V2RayAPI))
v2rayServer, err := experimental.NewV2RayServer(logFactory.NewLogger("v2ray-api"), common.PtrValueOrDefault(options.Experimental.V2RayAPI))
if err != nil {
return nil, E.Cause(err, "create v2ray api server")
}
+1 -3
View File
@@ -5,10 +5,8 @@ package badtls
import (
"crypto/tls"
"os"
aTLS "github.com/sagernet/sing/common/tls"
)
func Create(conn *tls.Conn) (aTLS.Conn, error) {
func Create(conn *tls.Conn) (TLSConn, error) {
return nil, os.ErrInvalid
}
+6 -13
View File
@@ -13,11 +13,12 @@ import (
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/tfo-go"
)
type DefaultDialer struct {
dialer4 tcpDialer
dialer6 tcpDialer
dialer4 tfo.Dialer
dialer6 tfo.Dialer
udpDialer4 net.Dialer
udpDialer6 net.Dialer
udpListener net.ListenConfig
@@ -93,22 +94,14 @@ func NewDefault(router adapter.Router, options option.DialerOptions) (*DefaultDi
udpAddr6 = M.SocksaddrFrom(bindAddr, 0).String()
}
if options.TCPMultiPath {
if !go121Available {
if !multipathTCPAvailable {
return nil, E.New("MultiPath TCP requires go1.21, please recompile your binary.")
}
setMultiPathTCP(&dialer4)
}
tcpDialer4, err := newTCPDialer(dialer4, options.TCPFastOpen)
if err != nil {
return nil, err
}
tcpDialer6, err := newTCPDialer(dialer6, options.TCPFastOpen)
if err != nil {
return nil, err
}
return &DefaultDialer{
tcpDialer4,
tcpDialer6,
tfo.Dialer{Dialer: dialer4, DisableTFO: !options.TCPFastOpen},
tfo.Dialer{Dialer: dialer6, DisableTFO: !options.TCPFastOpen},
udpDialer4,
udpDialer6,
listener,
-15
View File
@@ -1,15 +0,0 @@
//go:build go1.20
package dialer
import (
"net"
"github.com/sagernet/tfo-go"
)
type tcpDialer = tfo.Dialer
func newTCPDialer(dialer net.Dialer, tfoEnabled bool) (tcpDialer, error) {
return tfo.Dialer{Dialer: dialer, DisableTFO: !tfoEnabled}, nil
}
+1 -1
View File
@@ -4,7 +4,7 @@ package dialer
import "net"
const go121Available = true
const multipathTCPAvailable = true
func setMultiPathTCP(dialer *net.Dialer) {
dialer.SetMultipathTCP(true)
-18
View File
@@ -1,18 +0,0 @@
//go:build !go1.20
package dialer
import (
"net"
E "github.com/sagernet/sing/common/exceptions"
)
type tcpDialer = net.Dialer
func newTCPDialer(dialer net.Dialer, tfoEnabled bool) (tcpDialer, error) {
if tfoEnabled {
return dialer, E.New("TCP Fast Open requires go1.20, please recompile your binary.")
}
return dialer, nil
}
+1 -1
View File
@@ -6,7 +6,7 @@ import (
"net"
)
const go121Available = false
const multipathTCPAvailable = false
func setMultiPathTCP(dialer *net.Dialer) {
}
+1 -4
View File
@@ -1,5 +1,3 @@
//go:build go1.20
package dialer
import (
@@ -27,7 +25,7 @@ type slowOpenConn struct {
err error
}
func DialSlowContext(dialer *tcpDialer, ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
func DialSlowContext(dialer *tfo.Dialer, ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
if dialer.DisableTFO || N.NetworkName(network) != N.NetworkTCP {
switch N.NetworkName(network) {
case N.NetworkTCP, N.NetworkUDP:
@@ -63,7 +61,6 @@ func (c *slowOpenConn) Write(b []byte) (n int, err error) {
if c.conn == nil {
c.conn, err = c.dialer.DialContext(c.ctx, c.network, c.destination.String(), b)
if err != nil {
c.conn = nil
c.err = E.Cause(err, "dial tcp fast open")
}
close(c.create)
-20
View File
@@ -1,20 +0,0 @@
//go:build !go1.20
package dialer
import (
"context"
"net"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
func DialSlowContext(dialer *tcpDialer, ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
switch N.NetworkName(network) {
case N.NetworkTCP, N.NetworkUDP:
return dialer.DialContext(ctx, network, destination.String())
default:
return dialer.DialContext(ctx, network, destination.AddrString())
}
}
-28
View File
@@ -1,31 +1,3 @@
#### 1.4.0-beta.6
* Add `udp_over_stream` option for TUIC client **1**
* Add `include_interface` and `exclude_interface` options for tun inbound
* Fixes and improvements
**1**:
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
another program compatible with the protocol as a server.
This mode has no positive effect in a proper UDP proxy scenario and should only be applied to relay streaming UDP
traffic (basically QUIC streams).
#### 1.4.0-beta.5
* Fixes and improvements
#### 1.4.0-beta.4
* Graphical clients: Persistence group expansion state
* Fixes and improvements
#### 1.4.0-beta.3
* Fixes and improvements
#### 1.4.0-beta.2
* Add MultiPath TCP support **1**
-22
View File
@@ -24,12 +24,6 @@
],
"endpoint_independent_nat": false,
"stack": "system",
"include_interface": [
"lan0"
],
"exclude_interface": [
"lan1"
],
"include_uid": [
0
],
@@ -159,22 +153,6 @@ TCP/IP stack.
gVisor and LWIP stacks is not included by default, see [Installation](/#installation).
#### include_interface
!!! error ""
Interface rules are only supported on Linux and require auto_route.
Limit interfaces in route. Not limited by default.
Conflict with `exclude_interface`.
#### exclude_interface
Exclude interfaces in route.
Conflict with `include_interface`.
#### include_uid
!!! error ""
-22
View File
@@ -24,12 +24,6 @@
],
"endpoint_independent_nat": false,
"stack": "system",
"include_interface": [
"lan0"
],
"exclude_interface": [
"lan1"
],
"include_uid": [
0
],
@@ -155,22 +149,6 @@ TCP/IP 栈。
默认安装不包含 gVisor 和 LWIP 栈,请参阅 [安装](/zh/#_2)。
#### include_interface
!!! error ""
接口规则仅在 Linux 下被支持,并且需要 `auto_route`。
限制被路由的接口。默认不限制。
与 `exclude_interface` 冲突。
#### exclude_interface
排除路由的接口。
与 `include_interface` 冲突。
#### include_uid
!!! error ""
-14
View File
@@ -11,7 +11,6 @@
"password": "hello",
"congestion_control": "cubic",
"udp_relay_mode": "native",
"udp_over_stream": false,
"zero_rtt_handshake": false,
"heartbeat": "10s",
"network": "tcp",
@@ -68,19 +67,6 @@ UDP packet relay mode
`native` is used by default.
Conflict with `udp_over_stream`.
#### udp_over_stream
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
another program compatible with the protocol as a server.
This mode has no positive effect in a proper UDP proxy scenario and should only be applied to relay streaming UDP
traffic (basically QUIC streams).
Conflict with `udp_relay_mode`.
#### network
Enabled network
-10
View File
@@ -11,7 +11,6 @@
"password": "hello",
"congestion_control": "cubic",
"udp_relay_mode": "native",
"udp_over_stream": false,
"zero_rtt_handshake": false,
"heartbeat": "10s",
"network": "tcp",
@@ -66,15 +65,6 @@ UDP 包中继模式
| native | 原生 UDP |
| quic | 使用 QUIC 流的无损 UDP 中继,引入了额外的开销 |
与 `udp_over_stream` 冲突。
#### udp_over_stream
这是 TUIC 的 [UDP over TCP 协议](/configuration/shared/udp-over-tcp) 移植, 旨在提供 TUIC 不提供的 基于 QUIC 流的 UDP 中继模式。 由于它是一个附加协议,因此您需要使用 sing-box 或其他兼容的程序作为服务器。
此模式在正确的 UDP 代理场景中没有任何积极作用,仅适用于中继流式 UDP 流量(基本上是 QUIC 流)。
与 `udp_relay_mode` 冲突。
#### zero_rtt_handshake
+1
View File
@@ -24,6 +24,7 @@
|------------|-------------------------|
| `geoip` | [GeoIP](./geoip) |
| `geosite` | [GeoSite](./geosite) |
| `ip_rules` | 一组 [IP 路由规则](./ip-rule) |
| `rules` | 一组 [路由规则](./rule) |
#### final
+205
View File
@@ -0,0 +1,205 @@
### Structure
```json
{
"route": {
"ip_rules": [
{
"inbound": [
"mixed-in"
],
"ip_version": 6,
"network": [
"tcp"
],
"domain": [
"test.com"
],
"domain_suffix": [
".cn"
],
"domain_keyword": [
"test"
],
"domain_regex": [
"^stun\\..+"
],
"geosite": [
"cn"
],
"source_geoip": [
"private"
],
"geoip": [
"cn"
],
"source_ip_cidr": [
"10.0.0.0/24",
"192.168.0.1"
],
"ip_cidr": [
"10.0.0.0/24",
"192.168.0.1"
],
"source_port": [
12345
],
"source_port_range": [
"1000:2000",
":3000",
"4000:"
],
"port": [
80,
443
],
"port_range": [
"1000:2000",
":3000",
"4000:"
],
"invert": false,
"action": "direct",
"outbound": "wireguard"
},
{
"type": "logical",
"mode": "and",
"rules": [],
"invert": false,
"action": "direct",
"outbound": "wireguard"
}
]
}
}
```
!!! note ""
You can ignore the JSON Array [] tag when the content is only one item
### Default Fields
!!! note ""
The default rule uses the following matching logic:
(`domain` || `domain_suffix` || `domain_keyword` || `domain_regex` || `geosite` || `geoip` || `ip_cidr`) &&
(`port` || `port_range`) &&
(`source_geoip` || `source_ip_cidr`) &&
(`source_port` || `source_port_range`) &&
`other fields`
#### inbound
Tags of [Inbound](/configuration/inbound).
#### ip_version
4 or 6.
Not limited if empty.
#### network
Match network protocol.
Available values:
* `tcp`
* `udp`
* `icmpv4`
* `icmpv6`
#### domain
Match full domain.
#### domain_suffix
Match domain suffix.
#### domain_keyword
Match domain using keyword.
#### domain_regex
Match domain using regular expression.
#### geosite
Match geosite.
#### source_geoip
Match source geoip.
#### geoip
Match geoip.
#### source_ip_cidr
Match source ip cidr.
#### ip_cidr
Match ip cidr.
#### source_port
Match source port.
#### source_port_range
Match source port range.
#### port
Match port.
#### port_range
Match port range.
#### invert
Invert match result.
#### action
==Required==
| Action | Description |
|--------|--------------------------------------------------------------------|
| return | Stop IP routing and assemble the connection to the transport layer |
| block | Block the connection |
| direct | Directly forward the connection |
#### outbound
==Required if action is direct==
Tag of the target outbound.
Only outbound which supports IP connection can be used, see [Outbounds that support IP connection](/configuration/outbound/#outbounds-that-support-ip-connection).
### Logical Fields
#### type
`logical`
#### mode
==Required==
`and` or `or`
#### rules
==Required==
Included default rules.
+204
View File
@@ -0,0 +1,204 @@
### 结构
```json
{
"route": {
"ip_rules": [
{
"inbound": [
"mixed-in"
],
"ip_version": 6,
"network": [
"tcp"
],
"domain": [
"test.com"
],
"domain_suffix": [
".cn"
],
"domain_keyword": [
"test"
],
"domain_regex": [
"^stun\\..+"
],
"geosite": [
"cn"
],
"source_geoip": [
"private"
],
"geoip": [
"cn"
],
"source_ip_cidr": [
"10.0.0.0/24",
"192.168.0.1"
],
"ip_cidr": [
"10.0.0.0/24",
"192.168.0.1"
],
"source_port": [
12345
],
"source_port_range": [
"1000:2000",
":3000",
"4000:"
],
"port": [
80,
443
],
"port_range": [
"1000:2000",
":3000",
"4000:"
],
"invert": false,
"action": "direct",
"outbound": "wireguard"
},
{
"type": "logical",
"mode": "and",
"rules": [],
"invert": false,
"action": "direct",
"outbound": "wireguard"
}
]
}
}
```
!!! note ""
当内容只有一项时,可以忽略 JSON 数组 [] 标签。
### Default Fields
!!! note ""
默认规则使用以下匹配逻辑:
(`domain` || `domain_suffix` || `domain_keyword` || `domain_regex` || `geosite` || `geoip` || `ip_cidr`) &&
(`port` || `port_range`) &&
(`source_geoip` || `source_ip_cidr`) &&
(`source_port` || `source_port_range`) &&
`other fields`
#### inbound
[入站](/zh/configuration/inbound) 标签。
#### ip_version
4 或 6。
默认不限制。
#### network
匹配网络协议。
可用值:
* `tcp`
* `udp`
* `icmpv4`
* `icmpv6`
#### domain
匹配完整域名。
#### domain_suffix
匹配域名后缀。
#### domain_keyword
匹配域名关键字。
#### domain_regex
匹配域名正则表达式。
#### geosite
匹配 GeoSite。
#### source_geoip
匹配源 GeoIP。
#### geoip
匹配 GeoIP。
#### source_ip_cidr
匹配源 IP CIDR。
#### ip_cidr
匹配 IP CIDR。
#### source_port
匹配源端口。
#### source_port_range
匹配源端口范围。
#### port
匹配端口。
#### port_range
匹配端口范围。
#### invert
反选匹配结果。
#### action
==必填==
| Action | 描述 |
|--------|---------------------|
| return | 停止 IP 路由并将该连接组装到传输层 |
| block | 屏蔽该连接 |
| direct | 直接转发该连接 |
#### outbound
==action 为 direct 则必填==
目标出站的标签。
### 逻辑字段
#### type
`logical`
#### mode
==必填==
`and` 或 `or`
#### rules
==必填==
包括的默认规则。
+1
View File
@@ -8,4 +8,5 @@ Configuration examples for sing-box.
* [Shadowsocks](./shadowsocks)
* [ShadowTLS](./shadowtls)
* [Clash API](./clash-api)
* [WireGuard Direct](./wireguard-direct)
* [FakeIP](./fakeip)
+1
View File
@@ -8,4 +8,5 @@ sing-box 的配置示例。
* [Shadowsocks](./shadowsocks)
* [ShadowTLS](./shadowtls)
* [Clash API](./clash-api)
* [WireGuard Direct](./wireguard-direct)
* [FakeIP](./fakeip)
+90
View File
@@ -0,0 +1,90 @@
# WireGuard Direct
```json
{
"dns": {
"servers": [
{
"tag": "google",
"address": "tls://8.8.8.8"
},
{
"tag": "local",
"address": "223.5.5.5",
"detour": "direct"
}
],
"rules": [
{
"geoip": "cn",
"server": "direct"
}
],
"reverse_mapping": true
},
"inbounds": [
{
"type": "tun",
"tag": "tun",
"inet4_address": "172.19.0.1/30",
"auto_route": true,
"sniff": true,
"stack": "system"
}
],
"outbounds": [
{
"type": "wireguard",
"tag": "wg",
"server": "127.0.0.1",
"server_port": 2345,
"local_address": [
"172.19.0.1/128"
],
"private_key": "KLTnpPY03pig/WC3zR8U7VWmpANHPFh2/4pwICGJ5Fk=",
"peer_public_key": "uvNabcamf6Rs0vzmcw99jsjTJbxo6eWGOykSY66zsUk="
},
{
"type": "dns",
"tag": "dns"
},
{
"type": "direct",
"tag": "direct"
},
{
"type": "block",
"tag": "block"
}
],
"route": {
"ip_rules": [
{
"port": 53,
"action": "return"
},
{
"geoip": "cn",
"geosite": "cn",
"action": "return"
},
{
"action": "direct",
"outbound": "wg"
}
],
"rules": [
{
"protocol": "dns",
"outbound": "dns"
},
{
"geoip": "cn",
"geosite": "cn",
"outbound": "direct"
}
],
"auto_detect_interface": true
}
}
```
+1 -1
View File
@@ -9,7 +9,7 @@ Experimental Android client for sing-box.
#### Download
* [AppCenter](https://install.appcenter.ms/users/nekohasekai/apps/sfa/distribution_groups/publictest)
* [Github Releases](https://github.com/SagerNet/sing-box/releases)
* [Github Releases](https://SagerNet/sing-box/releases)
#### Note
+1 -1
View File
@@ -9,7 +9,7 @@
#### 下载
* [AppCenter](https://install.appcenter.ms/users/nekohasekai/apps/sfa/distribution_groups/publictest)
* [Github Releases](https://github.com/SagerNet/sing-box/releases)
* [Github Releases](https://SagerNet/sing-box/releases)
#### 注意事项
+2 -13
View File
@@ -1,17 +1,6 @@
# Install from source
## Requirements
Before sing-box 1.4.0:
* Go 1.18.5 - 1.20.x
Since sing-box 1.4.0:
* Go 1.18.5 - ~
* Go 1.20.0 - ~ if `with_quic` tag enabled
## Installation
sing-box requires Golang **1.18.5** or a higher version.
```bash
go install -v github.com/sagernet/sing-box/cmd/sing-box@latest
@@ -20,7 +9,7 @@ go install -v github.com/sagernet/sing-box/cmd/sing-box@latest
Install with options:
```bash
go install -v -tags with_quic,with_wireguard github.com/sagernet/sing-box/cmd/sing-box@latest
go install -v -tags with_clash_api github.com/sagernet/sing-box/cmd/sing-box@latest
```
| Build Tag | Description |
+11 -38
View File
@@ -12,10 +12,7 @@ import (
"go.etcd.io/bbolt"
)
var (
bucketSelected = []byte("selected")
bucketExpand = []byte("group_expand")
)
var bucketSelected = []byte("selected")
var _ adapter.ClashCacheFile = (*CacheFile)(nil)
@@ -52,15 +49,21 @@ func Open(path string, cacheID string) (*CacheFile, error) {
if name[0] == 0 {
return b.ForEachBucket(func(k []byte) error {
bucketName := string(k)
if !(bucketName == string(bucketSelected) || bucketName == string(bucketExpand)) {
_ = b.DeleteBucket(name)
if !(bucketName == string(bucketSelected)) {
delErr := b.DeleteBucket(name)
if delErr != nil {
return delErr
}
}
return nil
})
} else {
bucketName := string(name)
if !(bucketName == string(bucketSelected) || bucketName == string(bucketExpand) || strings.HasPrefix(bucketName, fakeipBucketPrefix)) {
_ = tx.DeleteBucket(name)
if !(bucketName == string(bucketSelected) || strings.HasPrefix(bucketName, fakeipBucketPrefix)) {
delErr := tx.DeleteBucket(name)
if delErr != nil {
return delErr
}
}
}
return nil
@@ -126,36 +129,6 @@ func (c *CacheFile) StoreSelected(group, selected string) error {
})
}
func (c *CacheFile) LoadGroupExpand(group string) (isExpand bool, loaded bool) {
c.DB.View(func(t *bbolt.Tx) error {
bucket := c.bucket(t, bucketExpand)
if bucket == nil {
return nil
}
expandBytes := bucket.Get([]byte(group))
if len(expandBytes) == 1 {
isExpand = expandBytes[0] == 1
loaded = true
}
return nil
})
return
}
func (c *CacheFile) StoreGroupExpand(group string, isExpand bool) error {
return c.DB.Batch(func(t *bbolt.Tx) error {
bucket, err := c.createBucket(t, bucketExpand)
if err != nil {
return err
}
if isExpand {
return bucket.Put([]byte(group), []byte{1})
} else {
return bucket.Put([]byte(group), []byte{0})
}
})
}
func (c *CacheFile) Close() error {
return c.DB.Close()
}
+1 -1
View File
@@ -84,7 +84,7 @@ func NewServer(ctx context.Context, router adapter.Router, logFactory log.Observ
if server.mode == "" {
server.mode = "rule"
}
if options.StoreSelected || options.StoreFakeIP || options.ExternalController == "" {
if options.StoreSelected || options.StoreFakeIP {
cachePath := os.ExpandEnv(options.CacheFile)
if cachePath == "" {
cachePath = "cache.db"
-1
View File
@@ -8,5 +8,4 @@ const (
CommandGroup
CommandSelectOutbound
CommandURLTest
CommandGroupExpand
)
+1 -1
View File
@@ -32,7 +32,7 @@ func NewStandaloneCommandClient() *CommandClient {
return new(CommandClient)
}
func NewCommandClient(handler CommandClientHandler, options *CommandClientOptions) *CommandClient {
func NewCommandClient(sharedDirectory string, handler CommandClientHandler, options *CommandClientOptions) *CommandClient {
return &CommandClient{
handler: handler,
options: common.PtrValueOrDefault(options),
-67
View File
@@ -9,7 +9,6 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/urltest"
"github.com/sagernet/sing-box/outbound"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/rw"
"github.com/sagernet/sing/service"
)
@@ -19,7 +18,6 @@ type OutboundGroup struct {
Type string
Selectable bool
Selected string
IsExpand bool
items []*OutboundGroupItem
}
@@ -116,11 +114,6 @@ func readGroups(reader io.Reader) (OutboundGroupIterator, error) {
return nil, err
}
err = binary.Read(reader, binary.BigEndian, &group.IsExpand)
if err != nil {
return nil, err
}
var itemLength uint16
err = binary.Read(reader, binary.BigEndian, &itemLength)
if err != nil {
@@ -159,10 +152,6 @@ func readGroups(reader io.Reader) (OutboundGroupIterator, error) {
func writeGroups(writer io.Writer, boxService *BoxService) error {
historyStorage := service.PtrFromContext[urltest.HistoryStorage](boxService.ctx)
var cacheFile adapter.ClashCacheFile
if clashServer := boxService.instance.Router().ClashServer(); clashServer != nil {
cacheFile = clashServer.CacheFile()
}
outbounds := boxService.instance.Router().Outbounds()
var iGroups []adapter.OutboundGroup
@@ -178,11 +167,6 @@ func writeGroups(writer io.Writer, boxService *BoxService) error {
group.Type = iGroup.Type()
_, group.Selectable = iGroup.(*outbound.Selector)
group.Selected = iGroup.Now()
if cacheFile != nil {
if isExpand, loaded := cacheFile.LoadGroupExpand(group.Tag); loaded {
group.IsExpand = isExpand
}
}
for _, itemTag := range iGroup.All() {
itemOutbound, isLoaded := boxService.instance.Router().Outbound(itemTag)
@@ -223,10 +207,6 @@ func writeGroups(writer io.Writer, boxService *BoxService) error {
if err != nil {
return err
}
err = binary.Write(writer, binary.BigEndian, group.IsExpand)
if err != nil {
return err
}
err = binary.Write(writer, binary.BigEndian, uint16(len(group.items)))
if err != nil {
return err
@@ -252,50 +232,3 @@ func writeGroups(writer io.Writer, boxService *BoxService) error {
}
return nil
}
func (c *CommandClient) SetGroupExpand(groupTag string, isExpand bool) error {
conn, err := c.directConnect()
if err != nil {
return err
}
defer conn.Close()
err = binary.Write(conn, binary.BigEndian, uint8(CommandGroupExpand))
if err != nil {
return err
}
err = rw.WriteVString(conn, groupTag)
if err != nil {
return err
}
err = binary.Write(conn, binary.BigEndian, isExpand)
if err != nil {
return err
}
return readError(conn)
}
func (s *CommandServer) handleSetGroupExpand(conn net.Conn) error {
defer conn.Close()
groupTag, err := rw.ReadVString(conn)
if err != nil {
return err
}
var isExpand bool
err = binary.Read(conn, binary.BigEndian, &isExpand)
if err != nil {
return err
}
service := s.service
if service == nil {
return writeError(conn, E.New("service not ready"))
}
if clashServer := service.instance.Router().ClashServer(); clashServer != nil {
if cacheFile := clashServer.CacheFile(); cacheFile != nil {
err = cacheFile.StoreGroupExpand(groupTag, isExpand)
if err != nil {
return writeError(conn, err)
}
}
}
return writeError(conn, nil)
}
-2
View File
@@ -154,8 +154,6 @@ func (s *CommandServer) handleConnection(conn net.Conn) error {
return s.handleSelectOutbound(conn)
case CommandURLTest:
return s.handleURLTest(conn)
case CommandGroupExpand:
return s.handleSetGroupExpand(conn)
default:
return E.New("unknown command: ", command)
}
-3
View File
@@ -3,7 +3,6 @@ package libbox
import (
"context"
"net/netip"
runtimeDebug "runtime/debug"
"syscall"
"github.com/sagernet/sing-box"
@@ -36,7 +35,6 @@ func NewService(configContent string, platformInterface PlatformInterface) (*Box
if err != nil {
return nil, err
}
runtimeDebug.FreeOSMemory()
ctx, cancel := context.WithCancel(context.Background())
ctx = filemanager.WithDefault(ctx, sWorkingPath, sTempPath, sUserID, sGroupID)
ctx = service.ContextWithPtr(ctx, urltest.NewHistoryStorage())
@@ -51,7 +49,6 @@ func NewService(configContent string, platformInterface PlatformInterface) (*Box
cancel()
return nil, E.Cause(err, "create service")
}
runtimeDebug.FreeOSMemory()
return &BoxService{
ctx: ctx,
cancel: cancel,
+7 -7
View File
@@ -1,6 +1,6 @@
module github.com/sagernet/sing-box
go 1.20
go 1.18
require (
berty.tech/go-libtor v1.0.385
@@ -23,18 +23,18 @@ require (
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0
github.com/sagernet/gomobile v0.0.0-20230728014906-3de089147f59
github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2
github.com/sagernet/quic-go v0.0.0-20230811130919-d6f54a117913
github.com/sagernet/quic-go v0.0.0-20230809023643-d720ed35ac2b
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
github.com/sagernet/sing v0.2.10-0.20230820051732-fabfb87d9f29
github.com/sagernet/sing v0.2.10-0.20230807080248-4db0062caa0a
github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659
github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c
github.com/sagernet/sing-mux v0.1.3-0.20230803070305-ea4a972acd21
github.com/sagernet/sing-shadowsocks v0.2.4
github.com/sagernet/sing-shadowsocks2 v0.1.3
github.com/sagernet/sing-shadowtls v0.1.4
github.com/sagernet/sing-tun v0.1.12-0.20230820091922-db70908d6125
github.com/sagernet/sing-tun v0.1.12-0.20230808120247-47ab78d303db
github.com/sagernet/sing-vmess v0.1.7
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6
github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e
github.com/sagernet/wireguard-go v0.0.0-20230807125731-5d4a7ef2dc5f
@@ -60,7 +60,7 @@ require (
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/cloudflare/circl v1.2.1-0.20221019164342-6ab4dfed8f3c // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
+13 -13
View File
@@ -34,8 +34,8 @@ github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vz
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
@@ -107,32 +107,32 @@ github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2 h1:dnkKrzapqtAwjTS
github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2/go.mod h1:1JUiV7nGuf++YFm9eWZ8q2lrwHmhcUGzptMl/vL1+LA=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/quic-go v0.0.0-20230811130919-d6f54a117913 h1:4dyzZWAEo9BNQN7yJsVSiN/Pm1hmUfkGJdEyWMkUnVE=
github.com/sagernet/quic-go v0.0.0-20230811130919-d6f54a117913/go.mod h1:w+nln6f/ZtyPpGbFxmgd5iYFVMmgS+gpD5hu5GAqC1I=
github.com/sagernet/quic-go v0.0.0-20230809023643-d720ed35ac2b h1:+hpCW1zw03nnJDx+5tF9ETb6bKl2VSftv4KMGZAHC2Q=
github.com/sagernet/quic-go v0.0.0-20230809023643-d720ed35ac2b/go.mod h1:w+nln6f/ZtyPpGbFxmgd5iYFVMmgS+gpD5hu5GAqC1I=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
github.com/sagernet/sing v0.2.10-0.20230820051732-fabfb87d9f29 h1:TGSiSJ5noRdmDW0vd1sc/WICJWoT2ulOhD/igXh8PJc=
github.com/sagernet/sing v0.2.10-0.20230820051732-fabfb87d9f29/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA=
github.com/sagernet/sing v0.2.10-0.20230807080248-4db0062caa0a h1:b89t6Mjgk4rJ5lrNMnCzy1/J116XkhgdB3YNd9FHyF4=
github.com/sagernet/sing v0.2.10-0.20230807080248-4db0062caa0a/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA=
github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659 h1:1DAKccGNqTYJ8nsBR765FS0LVBVXfuFlFAHqKsGN3EI=
github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659/go.mod h1:W7GHTZFS8RkoLI3bA2LFY27/0E+uoQESWtMFLepO/JA=
github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c h1:35/FowAvt3Z62mck0TXzVc4jS5R5CWq62qcV2P1cp0I=
github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c/go.mod h1:TKxqIvfQQgd36jp2tzsPavGjYTVZilV+atip1cssjIY=
github.com/sagernet/sing-mux v0.1.3-0.20230803070305-ea4a972acd21 h1:IQ7oBBKz+lwIqwI9IMStlQ9YSUu3eKJmNTip0aLbvOI=
github.com/sagernet/sing-mux v0.1.3-0.20230803070305-ea4a972acd21/go.mod h1:TKxqIvfQQgd36jp2tzsPavGjYTVZilV+atip1cssjIY=
github.com/sagernet/sing-shadowsocks v0.2.4 h1:s/CqXlvFAZhlIoHWUwPw5CoNnQ9Ibki9pckjuugtVfY=
github.com/sagernet/sing-shadowsocks v0.2.4/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM=
github.com/sagernet/sing-shadowsocks2 v0.1.3 h1:WXoLvCFi5JTFBRYorf1YePGYIQyJ/zbsBM6Fwbl5kGA=
github.com/sagernet/sing-shadowsocks2 v0.1.3/go.mod h1:DOhJc/cLeqRv0wuePrQso+iUmDxOnWF4eT/oMcRzYFw=
github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4=
github.com/sagernet/sing-tun v0.1.12-0.20230820091922-db70908d6125 h1:ZqNuG9t4lAZbiqMSJN/nNv7ZtRRpm7h46KrmnkuhW9w=
github.com/sagernet/sing-tun v0.1.12-0.20230820091922-db70908d6125/go.mod h1:+YImslQMLgMQcVgZZ9IK4ue1o/605VSU90amHUcp4hA=
github.com/sagernet/sing-tun v0.1.12-0.20230808120247-47ab78d303db h1:jOwG+7u4NtQVwXj5pFnGeNnDoa2cv83O5x4NLKN8y/c=
github.com/sagernet/sing-tun v0.1.12-0.20230808120247-47ab78d303db/go.mod h1:XsyIVKd/Qp+2SdLZWGbavHtcpE7J7XU3S1zJmcoj9Ck=
github.com/sagernet/sing-vmess v0.1.7 h1:TM8FFLsXmlXH9XT8/oDgc6PC5BOzrg6OzyEe01is2r4=
github.com/sagernet/sing-vmess v0.1.7/go.mod h1:1qkC1L1T2sxnS/NuO6HU72S8TkltV+EXoKGR29m/Yss=
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as=
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37/go.mod h1:3skNSftZDJWTGVtVaM2jfbce8qHnmH/AGDRe62iNOg0=
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6 h1:Px+hN4Vzgx+iCGVnWH5A8eR7JhNnIV3rGQmBxA7cw6Q=
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6/go.mod h1:zovq6vTvEM6ECiqE3Eeb9rpIylPpamPcmrJ9tv0Bt0M=
github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 h1:2ItpW1nMNkPzmBTxV0/eClCklHrFSQMnUGcpUmJxVeE=
github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9/go.mod h1:FUyTEc5ye5NjKnDTDMuiLF2M6T4BE6y6KZuax//UCEg=
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 h1:kDUqhc9Vsk5HJuhfIATJ8oQwBmpOZJuozQG7Vk88lL4=
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2/go.mod h1:JKQMZq/O2qnZjdrt+B57olmfgEmLtY9iiSIEYtWvoSM=
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e h1:7uw2njHFGE+VpWamge6o56j2RWk4omF6uLKKxMmcWvs=
@@ -195,6 +195,7 @@ golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -204,7 +205,6 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+10 -12
View File
@@ -10,26 +10,24 @@ import (
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/tfo-go"
)
func (a *myInboundAdapter) ListenTCP() (net.Listener, error) {
var err error
bindAddr := M.SocksaddrFrom(a.listenOptions.Listen.Build(), a.listenOptions.ListenPort)
var tcpListener net.Listener
var listenConfig net.ListenConfig
if a.listenOptions.TCPMultiPath {
if !go121Available {
return nil, E.New("MultiPath TCP requires go1.21, please recompile your binary.")
if !a.listenOptions.TCPFastOpen {
var listenConfig net.ListenConfig
if a.listenOptions.TCPMultiPath {
if !multipathTCPAvailable {
return nil, E.New("MultiPath TCP requires go1.21, please recompile your binary.")
}
setMultiPathTCP(&listenConfig)
}
setMultiPathTCP(&listenConfig)
}
if a.listenOptions.TCPFastOpen {
if !go120Available {
return nil, E.New("TCP Fast Open requires go1.20, please recompile your binary.")
}
tcpListener, err = listenTFO(listenConfig, a.ctx, M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.String())
} else {
tcpListener, err = listenConfig.Listen(a.ctx, M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.String())
} else {
tcpListener, err = tfo.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
}
if err == nil {
a.logger.Info("tcp server started at ", tcpListener.Addr())
-18
View File
@@ -1,18 +0,0 @@
//go:build go1.20
package inbound
import (
"context"
"net"
"github.com/sagernet/tfo-go"
)
const go120Available = true
func listenTFO(listenConfig net.ListenConfig, ctx context.Context, network string, address string) (net.Listener, error) {
var tfoConfig tfo.ListenConfig
tfoConfig.ListenConfig = listenConfig
return tfoConfig.Listen(ctx, network, address)
}
+1 -1
View File
@@ -4,7 +4,7 @@ package inbound
import "net"
const go121Available = true
const multipathTCPAvailable = true
func setMultiPathTCP(listenConfig *net.ListenConfig) {
listenConfig.SetMultipathTCP(true)
-15
View File
@@ -1,15 +0,0 @@
//go:build !go1.20
package inbound
import (
"context"
"net"
"os"
)
const go120Available = false
func listenTFO(listenConfig net.ListenConfig, ctx context.Context, network string, address string) (net.Listener, error) {
return nil, os.ErrInvalid
}
+1 -1
View File
@@ -4,7 +4,7 @@ package inbound
import "net"
const go121Available = false
const multipathTCPAvailable = false
func setMultiPathTCP(listenConfig *net.ListenConfig) {
}
-2
View File
@@ -77,8 +77,6 @@ func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger
Inet6Address: common.Map(options.Inet6Address, option.ListenPrefix.Build),
AutoRoute: options.AutoRoute,
StrictRoute: options.StrictRoute,
IncludeInterface: options.IncludeInterface,
ExcludeInterface: options.ExcludeInterface,
Inet4RouteAddress: common.Map(options.Inet4RouteAddress, option.ListenPrefix.Build),
Inet6RouteAddress: common.Map(options.Inet6RouteAddress, option.ListenPrefix.Build),
IncludeUID: includeUID,
+1 -2
View File
@@ -86,7 +86,6 @@ nav:
- Hysteria: configuration/inbound/hysteria.md
- ShadowTLS: configuration/inbound/shadowtls.md
- VLESS: configuration/inbound/vless.md
- TUIC: configuration/inbound/tuic.md
- Tun: configuration/inbound/tun.md
- Redirect: configuration/inbound/redirect.md
- TProxy: configuration/inbound/tproxy.md
@@ -104,7 +103,6 @@ nav:
- ShadowTLS: configuration/outbound/shadowtls.md
- ShadowsocksR: configuration/outbound/shadowsocksr.md
- VLESS: configuration/outbound/vless.md
- TUIC: configuration/outbound/tuic.md
- Tor: configuration/outbound/tor.md
- SSH: configuration/outbound/ssh.md
- DNS: configuration/outbound/dns.md
@@ -122,6 +120,7 @@ nav:
- Shadowsocks: examples/shadowsocks.md
- ShadowTLS: examples/shadowtls.md
- Clash API: examples/clash-api.md
- WireGuard Direct: examples/wireguard-direct.md
- FakeIP: examples/fakeip.md
- Contributing:
- contributing/index.md
-1
View File
@@ -23,7 +23,6 @@ type TUICOutboundOptions struct {
Password string `json:"password,omitempty"`
CongestionControl string `json:"congestion_control,omitempty"`
UDPRelayMode string `json:"udp_relay_mode,omitempty"`
UDPOverStream bool `json:"udp_over_stream,omitempty"`
ZeroRTTHandshake bool `json:"zero_rtt_handshake,omitempty"`
Heartbeat Duration `json:"heartbeat,omitempty"`
Network NetworkList `json:"network,omitempty"`
-2
View File
@@ -9,8 +9,6 @@ type TunInboundOptions struct {
StrictRoute bool `json:"strict_route,omitempty"`
Inet4RouteAddress Listable[ListenPrefix] `json:"inet4_route_address,omitempty"`
Inet6RouteAddress Listable[ListenPrefix] `json:"inet6_route_address,omitempty"`
IncludeInterface Listable[string] `json:"include_interface,omitempty"`
ExcludeInterface Listable[string] `json:"exclude_interface,omitempty"`
IncludeUID Listable[uint32] `json:"include_uid,omitempty"`
IncludeUIDRange Listable[string] `json:"include_uid_range,omitempty"`
ExcludeUID Listable[uint32] `json:"exclude_uid,omitempty"`
+1
View File
@@ -54,6 +54,7 @@ func NewShadowsocksR(ctx context.Context, router adapter.Router, logger log.Cont
serverAddr: options.ServerOptions.Build(),
}
var cipher string
var err error
switch options.Method {
case "none":
cipher = "dummy"
+11 -41
View File
@@ -20,7 +20,6 @@ import (
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/uot"
"github.com/gofrs/uuid/v5"
)
@@ -32,8 +31,7 @@ var (
type TUIC struct {
myOutboundAdapter
client *tuic.Client
udpStream bool
client *tuic.Client
}
func NewTUIC(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TUICOutboundOptions) (*TUIC, error) {
@@ -53,14 +51,11 @@ func NewTUIC(ctx context.Context, router adapter.Router, logger log.ContextLogge
if err != nil {
return nil, E.Cause(err, "invalid uuid")
}
var tuicUDPStream bool
if options.UDPOverStream && options.UDPRelayMode != "" {
return nil, E.New("udp_over_stream is conflict with udp_relay_mode")
}
var udpStream bool
switch options.UDPRelayMode {
case "native":
case "quic":
tuicUDPStream = true
udpStream = true
}
outboundDialer, err := dialer.New(router, options.DialerOptions)
if err != nil {
@@ -74,7 +69,7 @@ func NewTUIC(ctx context.Context, router adapter.Router, logger log.ContextLogge
UUID: userUUID,
Password: options.Password,
CongestionControl: options.CongestionControl,
UDPStream: tuicUDPStream,
UDPStream: udpStream,
ZeroRTTHandshake: options.ZeroRTTHandshake,
Heartbeat: time.Duration(options.Heartbeat),
})
@@ -90,8 +85,7 @@ func NewTUIC(ctx context.Context, router adapter.Router, logger log.ContextLogge
tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
},
client: client,
udpStream: options.UDPOverStream,
client: client,
}, nil
}
@@ -101,43 +95,19 @@ func (h *TUIC) DialContext(ctx context.Context, network string, destination M.So
h.logger.InfoContext(ctx, "outbound connection to ", destination)
return h.client.DialConn(ctx, destination)
case N.NetworkUDP:
if h.udpStream {
h.logger.InfoContext(ctx, "outbound stream packet connection to ", destination)
streamConn, err := h.client.DialConn(ctx, uot.RequestDestination(uot.Version))
if err != nil {
return nil, err
}
return uot.NewLazyConn(streamConn, uot.Request{
IsConnect: true,
Destination: destination,
}), nil
} else {
conn, err := h.ListenPacket(ctx, destination)
if err != nil {
return nil, err
}
return bufio.NewBindPacketConn(conn, destination), nil
conn, err := h.ListenPacket(ctx, destination)
if err != nil {
return nil, err
}
return bufio.NewBindPacketConn(conn, destination), nil
default:
return nil, E.New("unsupported network: ", network)
}
}
func (h *TUIC) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
if h.udpStream {
h.logger.InfoContext(ctx, "outbound stream packet connection to ", destination)
streamConn, err := h.client.DialConn(ctx, uot.RequestDestination(uot.Version))
if err != nil {
return nil, err
}
return uot.NewLazyConn(streamConn, uot.Request{
IsConnect: false,
Destination: destination,
}), nil
} else {
h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
return h.client.ListenPacket(ctx)
}
h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
return h.client.ListenPacket(ctx)
}
func (h *TUIC) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
+5 -8
View File
@@ -636,7 +636,6 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
if !loaded {
return E.New("missing fakeip context")
}
metadata.OriginDestination = metadata.Destination
metadata.Destination = M.Socksaddr{
Fqdn: domain,
Port: metadata.Destination.Port,
@@ -740,12 +739,13 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
}
metadata.Network = N.NetworkUDP
var originAddress M.Socksaddr
if r.fakeIPStore != nil && r.fakeIPStore.Contains(metadata.Destination.Addr) {
domain, loaded := r.fakeIPStore.Lookup(metadata.Destination.Addr)
if !loaded {
return E.New("missing fakeip context")
}
metadata.OriginDestination = metadata.Destination
originAddress = metadata.Destination
metadata.Destination = M.Socksaddr{
Fqdn: domain,
Port: metadata.Destination.Port,
@@ -759,7 +759,7 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
conn = deadline.NewPacketConn(bufio.NewNetPacketConn(conn))
}*/
if metadata.InboundOptions.SniffEnabled || metadata.Destination.Addr.IsUnspecified() {
if metadata.InboundOptions.SniffEnabled {
buffer := buf.NewPacket()
buffer.FullReset()
destination, err := conn.ReadPacket(buffer)
@@ -767,9 +767,6 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
buffer.Release()
return err
}
if metadata.Destination.Addr.IsUnspecified() {
metadata.Destination = destination
}
sniffMetadata, _ := sniff.PeekPacket(ctx, buffer.Bytes(), sniff.DomainNameQuery, sniff.QUICClientHello, sniff.STUNMessage)
if sniffMetadata != nil {
metadata.Protocol = sniffMetadata.Protocol
@@ -820,8 +817,8 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
conn = statsService.RoutedPacketConnection(metadata.Inbound, detour.Tag(), metadata.User, conn)
}
}
if metadata.FakeIP {
conn = fakeip.NewNATPacketConn(conn, metadata.OriginDestination, metadata.Destination)
if originAddress.IsValid() {
conn = fakeip.NewNATPacketConn(conn, originAddress, metadata.Destination)
}
return detour.NewPacketConnection(ctx, conn, metadata)
}
+7 -7
View File
@@ -1,6 +1,6 @@
module test
go 1.20
go 1.18
require github.com/sagernet/sing-box v0.0.0
@@ -10,7 +10,7 @@ require (
github.com/docker/docker v20.10.18+incompatible
github.com/docker/go-connections v0.4.0
github.com/gofrs/uuid/v5 v5.0.0
github.com/sagernet/sing v0.2.10-0.20230820051732-fabfb87d9f29
github.com/sagernet/sing v0.2.10-0.20230807080248-4db0062caa0a
github.com/sagernet/sing-shadowsocks v0.2.4
github.com/sagernet/sing-shadowsocks2 v0.1.3
github.com/spyzhov/ajson v0.7.1
@@ -37,7 +37,7 @@ require (
github.com/go-chi/chi/v5 v5.0.10 // indirect
github.com/go-chi/cors v1.2.1 // indirect
github.com/go-chi/render v1.0.3 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/mock v1.6.0 // indirect
@@ -70,15 +70,15 @@ require (
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect
github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2 // indirect
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
github.com/sagernet/quic-go v0.0.0-20230811130919-d6f54a117913 // indirect
github.com/sagernet/quic-go v0.0.0-20230809023643-d720ed35ac2b // indirect
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect
github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659 // indirect
github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c // indirect
github.com/sagernet/sing-mux v0.1.3-0.20230803070305-ea4a972acd21 // indirect
github.com/sagernet/sing-shadowtls v0.1.4 // indirect
github.com/sagernet/sing-tun v0.1.12-0.20230820091922-db70908d6125 // indirect
github.com/sagernet/sing-tun v0.1.12-0.20230808120247-47ab78d303db // indirect
github.com/sagernet/sing-vmess v0.1.7 // indirect
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 // indirect
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6 // indirect
github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 // indirect
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 // indirect
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e // indirect
github.com/sagernet/wireguard-go v0.0.0-20230807125731-5d4a7ef2dc5f // indirect
+15 -14
View File
@@ -44,8 +44,8 @@ github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vz
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
@@ -123,37 +123,38 @@ github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2 h1:dnkKrzapqtAwjTS
github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2/go.mod h1:1JUiV7nGuf++YFm9eWZ8q2lrwHmhcUGzptMl/vL1+LA=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/quic-go v0.0.0-20230811130919-d6f54a117913 h1:4dyzZWAEo9BNQN7yJsVSiN/Pm1hmUfkGJdEyWMkUnVE=
github.com/sagernet/quic-go v0.0.0-20230811130919-d6f54a117913/go.mod h1:w+nln6f/ZtyPpGbFxmgd5iYFVMmgS+gpD5hu5GAqC1I=
github.com/sagernet/quic-go v0.0.0-20230809023643-d720ed35ac2b h1:+hpCW1zw03nnJDx+5tF9ETb6bKl2VSftv4KMGZAHC2Q=
github.com/sagernet/quic-go v0.0.0-20230809023643-d720ed35ac2b/go.mod h1:w+nln6f/ZtyPpGbFxmgd5iYFVMmgS+gpD5hu5GAqC1I=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
github.com/sagernet/sing v0.2.10-0.20230820051732-fabfb87d9f29 h1:TGSiSJ5noRdmDW0vd1sc/WICJWoT2ulOhD/igXh8PJc=
github.com/sagernet/sing v0.2.10-0.20230820051732-fabfb87d9f29/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA=
github.com/sagernet/sing v0.2.10-0.20230807080248-4db0062caa0a h1:b89t6Mjgk4rJ5lrNMnCzy1/J116XkhgdB3YNd9FHyF4=
github.com/sagernet/sing v0.2.10-0.20230807080248-4db0062caa0a/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA=
github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659 h1:1DAKccGNqTYJ8nsBR765FS0LVBVXfuFlFAHqKsGN3EI=
github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659/go.mod h1:W7GHTZFS8RkoLI3bA2LFY27/0E+uoQESWtMFLepO/JA=
github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c h1:35/FowAvt3Z62mck0TXzVc4jS5R5CWq62qcV2P1cp0I=
github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c/go.mod h1:TKxqIvfQQgd36jp2tzsPavGjYTVZilV+atip1cssjIY=
github.com/sagernet/sing-mux v0.1.3-0.20230803070305-ea4a972acd21 h1:IQ7oBBKz+lwIqwI9IMStlQ9YSUu3eKJmNTip0aLbvOI=
github.com/sagernet/sing-mux v0.1.3-0.20230803070305-ea4a972acd21/go.mod h1:TKxqIvfQQgd36jp2tzsPavGjYTVZilV+atip1cssjIY=
github.com/sagernet/sing-shadowsocks v0.2.4 h1:s/CqXlvFAZhlIoHWUwPw5CoNnQ9Ibki9pckjuugtVfY=
github.com/sagernet/sing-shadowsocks v0.2.4/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM=
github.com/sagernet/sing-shadowsocks2 v0.1.3 h1:WXoLvCFi5JTFBRYorf1YePGYIQyJ/zbsBM6Fwbl5kGA=
github.com/sagernet/sing-shadowsocks2 v0.1.3/go.mod h1:DOhJc/cLeqRv0wuePrQso+iUmDxOnWF4eT/oMcRzYFw=
github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4=
github.com/sagernet/sing-tun v0.1.12-0.20230820091922-db70908d6125 h1:ZqNuG9t4lAZbiqMSJN/nNv7ZtRRpm7h46KrmnkuhW9w=
github.com/sagernet/sing-tun v0.1.12-0.20230820091922-db70908d6125/go.mod h1:+YImslQMLgMQcVgZZ9IK4ue1o/605VSU90amHUcp4hA=
github.com/sagernet/sing-tun v0.1.12-0.20230808120247-47ab78d303db h1:jOwG+7u4NtQVwXj5pFnGeNnDoa2cv83O5x4NLKN8y/c=
github.com/sagernet/sing-tun v0.1.12-0.20230808120247-47ab78d303db/go.mod h1:XsyIVKd/Qp+2SdLZWGbavHtcpE7J7XU3S1zJmcoj9Ck=
github.com/sagernet/sing-vmess v0.1.7 h1:TM8FFLsXmlXH9XT8/oDgc6PC5BOzrg6OzyEe01is2r4=
github.com/sagernet/sing-vmess v0.1.7/go.mod h1:1qkC1L1T2sxnS/NuO6HU72S8TkltV+EXoKGR29m/Yss=
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as=
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37/go.mod h1:3skNSftZDJWTGVtVaM2jfbce8qHnmH/AGDRe62iNOg0=
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6 h1:Px+hN4Vzgx+iCGVnWH5A8eR7JhNnIV3rGQmBxA7cw6Q=
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6/go.mod h1:zovq6vTvEM6ECiqE3Eeb9rpIylPpamPcmrJ9tv0Bt0M=
github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 h1:2ItpW1nMNkPzmBTxV0/eClCklHrFSQMnUGcpUmJxVeE=
github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9/go.mod h1:FUyTEc5ye5NjKnDTDMuiLF2M6T4BE6y6KZuax//UCEg=
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 h1:kDUqhc9Vsk5HJuhfIATJ8oQwBmpOZJuozQG7Vk88lL4=
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2/go.mod h1:JKQMZq/O2qnZjdrt+B57olmfgEmLtY9iiSIEYtWvoSM=
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e h1:7uw2njHFGE+VpWamge6o56j2RWk4omF6uLKKxMmcWvs=
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e/go.mod h1:45TUl8+gH4SIKr4ykREbxKWTxkDlSzFENzctB1dVRRY=
github.com/sagernet/wireguard-go v0.0.0-20230807125731-5d4a7ef2dc5f h1:Kvo8w8Y9lzFGB/7z09MJ3TR99TFtfI/IuY87Ygcycho=
github.com/sagernet/wireguard-go v0.0.0-20230420044414-a7bac1754e77 h1:g6QtRWQ2dKX7EQP++1JLNtw4C2TNxd4/ov8YUpOPOSo=
github.com/sagernet/wireguard-go v0.0.0-20230420044414-a7bac1754e77/go.mod h1:pJDdXzZIwJ+2vmnT0TKzmf8meeum+e2mTDSehw79eE0=
github.com/sagernet/wireguard-go v0.0.0-20230807125731-5d4a7ef2dc5f/go.mod h1:mySs0abhpc/gLlvhoq7HP1RzOaRmIXVeZGCh++zoApk=
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 h1:rc/CcqLH3lh8n+csdOuDfP+NuykE0U6AeYSJJHKDgSg=
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9/go.mod h1:a/83NAfUXvEuLpmxDssAXxgUgrEy12MId3Wd7OTs76s=
@@ -222,6 +223,7 @@ golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -234,7 +236,6 @@ golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=