Compare commits

..

7 Commits

Author SHA1 Message Date
世界
e48e5a309f documentation: Bump version & Refactor docs 2023-11-16 18:32:32 +08:00
世界
8060b30e56 Update quic-go to v0.40.0 2023-11-16 18:29:30 +08:00
世界
d7a3d4e493 Migrate multiplex and UoT server to inbound & Add tcp-brutal support for multiplex 2023-11-16 18:29:26 +08:00
世界
2e051cb456 Add support for v2ray http upgrade transport 2023-11-16 18:28:22 +08:00
世界
fcba386b4e Add exclude route support for tun 2023-11-16 18:28:03 +08:00
世界
a7f3aabb72 Add udp_disable_domain_unmapping inbound listen option 2023-11-16 18:27:17 +08:00
世界
4f46b3f0dc Migrate to gobwas/ws 2023-11-16 18:26:19 +08:00
83 changed files with 382 additions and 1288 deletions

View File

@@ -43,7 +43,7 @@ type OutboundGroup interface {
type URLTestGroup interface {
OutboundGroup
URLTest(ctx context.Context) (map[string]uint16, error)
URLTest(ctx context.Context, url string) (map[string]uint16, error)
}
func OutboundTag(detour Outbound) string {

View File

@@ -15,7 +15,6 @@ import (
type Router interface {
Service
PostStarter
Outbounds() []Outbound
Outbound(tag string) (Outbound, bool)
@@ -42,7 +41,6 @@ type Router interface {
NetworkMonitor() tun.NetworkUpdateMonitor
InterfaceMonitor() tun.DefaultInterfaceMonitor
PackageManager() tun.PackageManager
WIFIState() WIFIState
Rules() []Rule
ClashServer() ClashServer
@@ -80,8 +78,3 @@ type DNSRule interface {
type InterfaceUpdateListener interface {
InterfaceUpdated()
}
type WIFIState struct {
SSID string
BSSID string
}

17
box.go
View File

@@ -56,7 +56,7 @@ func New(options Options) (*Box, error) {
applyDebugOptions(common.PtrValueOrDefault(experimentalOptions.Debug))
var needClashAPI bool
var needV2RayAPI bool
if experimentalOptions.ClashAPI != nil || options.PlatformLogWriter != nil {
if experimentalOptions.ClashAPI != nil || options.PlatformInterface != nil {
needClashAPI = true
}
if experimentalOptions.V2RayAPI != nil && experimentalOptions.V2RayAPI.Listen != "" {
@@ -258,7 +258,7 @@ func (s *Box) start() error {
return E.Cause(err, "initialize inbound/", in.Type(), "[", tag, "]")
}
}
return s.postStart()
return nil
}
func (s *Box) postStart() error {
@@ -269,17 +269,16 @@ func (s *Box) postStart() error {
return E.Cause(err, "start ", serviceName)
}
}
for _, outbound := range s.outbounds {
if lateOutbound, isLateOutbound := outbound.(adapter.PostStarter); isLateOutbound {
s.logger.Trace("post-starting outbound/", outbound.Tag())
err := lateOutbound.PostStart()
for serviceName, service := range s.outbounds {
if lateService, isLateService := service.(adapter.PostStarter); isLateService {
s.logger.Trace("post-starting ", service)
err := lateService.PostStart()
if err != nil {
return E.Cause(err, "post-start outbound/", outbound.Tag())
return E.Cause(err, "post-start ", serviceName)
}
}
}
s.logger.Trace("post-starting router")
return s.router.PostStart()
return nil
}
func (s *Box) Close() error {

View File

@@ -6,6 +6,7 @@ import (
"sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing/common/bufio/deadline"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
@@ -44,7 +45,14 @@ func (d *DetourDialer) DialContext(ctx context.Context, network string, destinat
if err != nil {
return nil, err
}
return dialer.DialContext(ctx, network, destination)
conn, err := dialer.DialContext(ctx, network, destination)
if err != nil {
return nil, err
}
if deadline.NeedAdditionalReadDeadline(conn) {
conn = deadline.NewConn(conn)
}
return conn, nil
}
func (d *DetourDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {

View File

@@ -182,52 +182,11 @@ func QUICClientHello(ctx context.Context, packet []byte) (*adapter.InboundContex
break
}
switch frameType {
case 0x00: // PADDING
case 0x0:
continue
case 0x01: // PING
case 0x1:
continue
case 0x02, 0x03: // ACK
_, err = qtls.ReadUvarint(decryptedReader) // Largest Acknowledged
if err != nil {
return nil, err
}
_, err = qtls.ReadUvarint(decryptedReader) // ACK Delay
if err != nil {
return nil, err
}
ackRangeCount, err := qtls.ReadUvarint(decryptedReader) // ACK Range Count
if err != nil {
return nil, err
}
_, err = qtls.ReadUvarint(decryptedReader) // First ACK Range
if err != nil {
return nil, err
}
for i := 0; i < int(ackRangeCount); i++ {
_, err = qtls.ReadUvarint(decryptedReader) // Gap
if err != nil {
return nil, err
}
_, err = qtls.ReadUvarint(decryptedReader) // ACK Range Length
if err != nil {
return nil, err
}
}
if frameType == 0x03 {
_, err = qtls.ReadUvarint(decryptedReader) // ECT0 Count
if err != nil {
return nil, err
}
_, err = qtls.ReadUvarint(decryptedReader) // ECT1 Count
if err != nil {
return nil, err
}
_, err = qtls.ReadUvarint(decryptedReader) // ECN-CE Count
if err != nil {
return nil, err
}
}
case 0x06: // CRYPTO
case 0x6:
var offset uint64
offset, err = qtls.ReadUvarint(decryptedReader)
if err != nil {
@@ -249,26 +208,8 @@ func QUICClientHello(ctx context.Context, packet []byte) (*adapter.InboundContex
if err != nil {
return nil, err
}
case 0x1c: // CONNECTION_CLOSE
_, err = qtls.ReadUvarint(decryptedReader) // Error Code
if err != nil {
return nil, err
}
_, err = qtls.ReadUvarint(decryptedReader) // Frame Type
if err != nil {
return nil, err
}
var length uint64
length, err = qtls.ReadUvarint(decryptedReader) // Reason Phrase Length
if err != nil {
return nil, err
}
_, err = decryptedReader.Seek(int64(length), io.SeekCurrent) // Reason Phrase
if err != nil {
return nil, err
}
default:
return nil, os.ErrInvalid
// ignore unknown frame type
}
}
tlsHdr := make([]byte, 5)

View File

@@ -1,103 +1,4 @@
---
icon: material/alert-decagram
---
# ChangeLog
#### 1.7.3
* Fixes and improvements
_Due to the long waiting time, this version is no longer waiting for approval
by the Apple App Store, so updates to Apple Platforms will be delayed._
#### 1.7.2
* Fixes and improvements
#### 1.7.1
* Fixes and improvements
#### 1.7.0
* Fixes and improvements
Important changes since 1.6:
* Add [exclude route support](/configuration/inbound/tun) for TUN inbound
* Add `udp_disable_domain_unmapping` [inbound listen option](/configuration/shared/listen) **1**
* Add [HTTPUpgrade V2Ray transport](/configuration/shared/v2ray-transport#HTTPUpgrade) support **2**
* Migrate multiplex and UoT server to inbound **3**
* Add TCP Brutal support for multiplex **4**
* Add `wifi_ssid` and `wifi_bssid` route and DNS rules **5**
* Update quic-go to v0.40.0
* Update gVisor to 20231113.0
**1**:
If enabled, for UDP proxy requests addressed to a domain,
the original packet address will be sent in the response instead of the mapped domain.
This option is used for compatibility with clients that
do not support receiving UDP packets with domain addresses, such as Surge.
**2**:
Introduced in V2Ray 5.10.0.
The new HTTPUpgrade transport has better performance than WebSocket and is better suited for CDN abuse.
**3**:
Starting in 1.7.0, multiplexing support is no longer enabled by default
and needs to be turned on explicitly in inbound options.
**4**
Hysteria Brutal Congestion Control Algorithm in TCP. A kernel module needs to be installed on the Linux server,
see [TCP Brutal](/configuration/shared/tcp-brutal) for details.
**5**:
Only supported in graphical clients on Android and iOS.
#### 1.7.0-rc.3
* Fixes and improvements
#### 1.6.7
* macOS: Add button for uninstall SystemExtension in the standalone graphical client
* Fix missing UDP user context on TUIC/Hysteria2 inbounds
* Fixes and improvements
#### 1.7.0-rc.2
* Fix missing UDP user context on TUIC/Hysteria2 inbounds
* macOS: Add button for uninstall SystemExtension in the standalone graphical client
#### 1.6.6
* Fixes and improvements
#### 1.7.0-rc.1
* Fixes and improvements
#### 1.7.0-beta.5
* Update gVisor to 20231113.0
* Fixes and improvements
#### 1.7.0-beta.4
* Add `wifi_ssid` and `wifi_bssid` route and DNS rules **1**
* Fixes and improvements
**1**:
Only supported in graphical clients on Android and iOS.
# :material-alert-decagram: ChangeLog
#### 1.7.0-beta.3
@@ -159,13 +60,11 @@ Only supported in graphical clients on Android and iOS.
**1**:
Starting in 1.7.0, multiplexing support is no longer enabled by default and needs to be turned on explicitly in inbound
options.
Starting in 1.7.0, multiplexing support is no longer enabled by default and needs to be turned on explicitly in inbound options.
**2**
Hysteria Brutal Congestion Control Algorithm in TCP. A kernel module needs to be installed on the Linux server,
see [TCP Brutal](/configuration/shared/tcp-brutal) for details.
Hysteria Brutal Congestion Control Algorithm in TCP. A kernel module needs to be installed on the Linux server, see [TCP Brutal](/configuration/shared/tcp-brutal) for details.
#### 1.7.0-alpha.3
@@ -232,8 +131,8 @@ When `auto_route` is enabled and `strict_route` is disabled, the device can now
**2**:
Built using Go 1.20, the last version that will run on
Windows 7, 8, Server 2008, Server 2012 and macOS 10.13 High Sierra, 10.14 Mojave.
Built using Go 1.20, the last version that will run on Windows 7, 8, Server 2008, Server 2012 and macOS 10.13 High Sierra, 10.14 Mojave.
#### 1.6.0-rc.4
@@ -246,8 +145,7 @@ Windows 7, 8, Server 2008, Server 2012 and macOS 10.13 High Sierra, 10.14 Mojave
**1**:
Built using Go 1.20, the last version that will run on
Windows 7, 8, Server 2008, Server 2012 and macOS 10.13 High Sierra, 10.14 Mojave.
Built using Go 1.20, the last version that will run on Windows 7, 8, Server 2008, Server 2012 and macOS 10.13 High Sierra, 10.14 Mojave.
#### 1.6.0-beta.4

View File

@@ -12,38 +12,28 @@ SFA allows you to run sing-box through ForegroundService or VpnService (when TUN
SFA provides an unprivileged TUN implementation through Android VpnService.
| TUN inbound option | Available | Note |
|-------------------------------|------------------|--------------------|
| `interface_name` | :material-close: | Managed by Android |
| `inet4_address` | :material-check: | / |
| `inet6_address` | :material-check: | / |
| `mtu` | :material-check: | / |
| `auto_route` | :material-check: | / |
| `strict_route` | :material-close: | Not implemented |
| `inet4_route_address` | :material-check: | / |
| `inet6_route_address` | :material-check: | / |
| `inet4_route_exclude_address` | :material-check: | / |
| `inet6_route_exclude_address` | :material-check: | / |
| `endpoint_independent_nat` | :material-check: | / |
| `stack` | :material-check: | / |
| `include_interface` | :material-close: | No permission |
| `exclude_interface` | :material-close: | No permission |
| `include_uid` | :material-close: | No permission |
| `exclude_uid` | :material-close: | No permission |
| `include_android_user` | :material-close: | No permission |
| `include_package` | :material-check: | / |
| `exclude_package` | :material-check: | / |
| `platform` | :material-check: | / |
| Route/DNS rule option | Available | Note |
|-----------------------|------------------|-----------------------------------|
| `process_name` | :material-close: | No permission |
| `process_path` | :material-close: | No permission |
| `package_name` | :material-check: | / |
| `user` | :material-close: | Use `package_name` instead |
| `user_id` | :material-close: | Use `package_name` instead |
| `wifi_ssid` | :material-check: | Fine location permission required |
| `wifi_bssid` | :material-check: | Fine location permission required |
| TUN inbound option | Available | Note |
|-------------------------------|-----------|--------------------|
| `interface_name` | ✖️ | Managed by Android |
| `inet4_address` | ✔️ | / |
| `inet6_address` | ✔️ | / |
| `mtu` | ✔️ | / |
| `auto_route` | ✔️ | / |
| `strict_route` | ✖️ | Not implemented |
| `inet4_route_address` | ✔️ | / |
| `inet6_route_address` | ✔️ | / |
| `inet4_route_exclude_address` | ✔️ | / |
| `inet6_route_exclude_address` | ✔️ | / |
| `endpoint_independent_nat` | ✔️ | / |
| `stack` | ✔️ | / |
| `include_interface` | ✖️ | No permission |
| `exclude_interface` | ✖️ | No permission |
| `include_uid` | ✖️ | No permission |
| `exclude_uid` | ✖️ | No permission |
| `include_android_user` | ✖️ | No permission |
| `include_package` | ✔️ | / |
| `exclude_package` | ✔️ | / |
| `platform` | ✔️ | / |
### Override

View File

@@ -1,8 +1,4 @@
---
icon: material/android
---
# sing-box for Android
# :material-android: sing-box for Android
SFA allows users to manage and run local or remote sing-box configuration files, and provides
platform-specific function implementation, such as TUN transparent proxy implementation.
@@ -15,8 +11,8 @@ platform-specific function implementation, such as TUN transparent proxy impleme
* [Play Store](https://play.google.com/store/apps/details?id=io.nekohasekai.sfa)
* [Play Store (Beta)](https://play.google.com/apps/testing/io.nekohasekai.sfa)
* [GitHub Releases](https://github.com/SagerNet/sing-box/releases)
* [Github Releases](https://github.com/SagerNet/sing-box/releases)
## :material-source-repository: Source code
* [GitHub](https://github.com/SagerNet/sing-box-for-android)
* [Github](https://github.com/SagerNet/sing-box-for-android)

View File

@@ -37,16 +37,6 @@ SFI/SFM/SFT provides an unprivileged TUN implementation through NetworkExtension
| `exclude_package` | ✖️ | Not implemented |
| `platform` | ✔️ | / |
| Route/DNS rule option | Available | Note |
|-----------------------|------------------|-----------------------|
| `process_name` | :material-close: | No permission |
| `process_path` | :material-close: | No permission |
| `package_name` | :material-close: | / |
| `user` | :material-close: | No permission |
| `user_id` | :material-close: | No permission |
| `wifi_ssid` | :material-alert: | Only supported on iOS |
| `wifi_bssid` | :material-alert: | Only supported on iOS |
### Chore
* Crash logs is located in `Settings` -> `View Service Log`

View File

@@ -1,8 +1,4 @@
---
icon: material/apple
---
# sing-box for Apple platforms
# :material-apple: sing-box for Apple platforms
SFI/SFM/SFT allows users to manage and run local or remote sing-box configuration files, and provides
platform-specific function implementation, such as TUN transparent proxy implementation.
@@ -14,19 +10,9 @@ platform-specific function implementation, such as TUN transparent proxy impleme
## :material-download: Download
* [App Store](https://apps.apple.com/us/app/sing-box/id6451272673)
* [AppStore](https://apps.apple.com/us/app/sing-box/id6451272673)
* [TestFlight (Beta)](https://testflight.apple.com/join/AcqO44FH)
## :material-file-download: Download (macOS standalone version)
* [Homebrew Cask](https://formulae.brew.sh/cask/sfm)
```bash
brew install sfm
```
* [GitHub Releases](https://github.com/SagerNet/sing-box/releases)
## :material-source-repository: Source code
* [GitHub](https://github.com/SagerNet/sing-box-for-apple)
* [Github](https://github.com/SagerNet/sing-box-for-apple)

View File

@@ -1,8 +1,4 @@
---
icon: material/pencil-ruler
---
# General
# :material-pencil-ruler: General
Describes and explains the functions implemented uniformly by sing-box graphical clients.

View File

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

View File

@@ -6,7 +6,7 @@
|---------------------------------------|-----------------------------------------|
| :material-android: Android | [sing-box for Android](./android) |
| :material-apple: iOS/macOS/Apple tvOS | [sing-box for Apple platforms](./apple) |
| :material-laptop: Desktop | 施工中 |
| TODO | / |
此处没有列出一些声称使用或以 sing-box 为卖点的第三方项目。此类项目维护者的动机是获得更多用户,即使它们提供友好的商业
VPN 客户端功能, 但代码质量很差且包含广告。

View File

@@ -1,8 +1,4 @@
---
icon: material/security
---
# Privacy policy
# :material-security: Privacy policy
sing-box and official graphics clients do not collect or share personal data,
and the data generated by the software is always on your device.

View File

@@ -79,12 +79,6 @@
1000
],
"clash_mode": "direct",
"wifi_ssid": [
"My WIFI"
],
"wifi_bssid": [
"00:00:00:00:00:00"
],
"invert": false,
"outbound": [
"direct"
@@ -194,7 +188,7 @@ Match port range.
#### process_name
!!! quote ""
!!! error ""
Only supported on Linux, Windows, and macOS.
@@ -202,7 +196,7 @@ Match process name.
#### process_path
!!! quote ""
!!! error ""
Only supported on Linux, Windows, and macOS.
@@ -214,7 +208,7 @@ Match android package name.
#### user
!!! quote ""
!!! error ""
Only supported on Linux.
@@ -222,7 +216,7 @@ Match user name.
#### user_id
!!! quote ""
!!! error ""
Only supported on Linux.
@@ -232,24 +226,6 @@ Match user id.
Match Clash mode.
#### wifi_ssid
<!-- md:version 1.7.0-beta.4 -->
!!! quote ""
Only supported in graphical clients on Android and iOS.
Match WiFi SSID.
#### wifi_bssid
!!! quote ""
Only supported in graphical clients on Android and iOS.
Match WiFi BSSID.
#### invert
Invert match result.

View File

@@ -78,12 +78,6 @@
1000
],
"clash_mode": "direct",
"wifi_ssid": [
"My WIFI"
],
"wifi_bssid": [
"00:00:00:00:00:00"
],
"invert": false,
"outbound": [
"direct"
@@ -191,7 +185,7 @@ DNS 查询类型。值可以为整数或者类型名称字符串。
#### process_name
!!! quote ""
!!! error ""
仅支持 Linux、Windows 和 macOS.
@@ -199,7 +193,7 @@ DNS 查询类型。值可以为整数或者类型名称字符串。
#### process_path
!!! quote ""
!!! error ""
仅支持 Linux、Windows 和 macOS.
@@ -211,7 +205,7 @@ DNS 查询类型。值可以为整数或者类型名称字符串。
#### user
!!! quote ""
!!! error ""
仅支持 Linux。
@@ -219,7 +213,7 @@ DNS 查询类型。值可以为整数或者类型名称字符串。
#### user_id
!!! quote ""
!!! error ""
仅支持 Linux。
@@ -229,22 +223,6 @@ DNS 查询类型。值可以为整数或者类型名称字符串。
匹配 Clash 模式。
#### wifi_ssid
!!! quote ""
仅在 Android 与 iOS 的图形客户端中支持。
匹配 WiFi SSID。
#### wifi_bssid
!!! quote ""
仅在 Android 与 iOS 的图形客户端中支持。
匹配 WiFi BSSID。
#### invert
反选匹配结果。

View File

@@ -44,7 +44,7 @@
### Clash API Fields
!!! quote ""
!!! error ""
Clash API is not included by default, see [Installation](./#installation).
@@ -110,7 +110,7 @@ If not empty, `store_selected` will use a separate store keyed by it.
### V2Ray API Fields
!!! quote ""
!!! error ""
V2Ray API is not included by default, see [Installation](./#installation).

View File

@@ -44,7 +44,7 @@
### Clash API 字段
!!! quote ""
!!! error ""
默认安装不包含 Clash API参阅 [安装](/zh/#_2)。
@@ -108,7 +108,7 @@ Clash 中的默认模式,默认使用 `Rule`。
### V2Ray API 字段
!!! quote ""
!!! error ""
默认安装不包含 V2Ray API参阅 [安装](/zh/#_2)。

View File

@@ -36,7 +36,7 @@ No authentication required if empty.
#### set_system_proxy
!!! quote ""
!!! error ""
Only supported on Linux, Android, Windows, and macOS.

View File

@@ -36,7 +36,7 @@ HTTP 用户
#### set_system_proxy
!!! quote ""
!!! error ""
仅支持 Linux、Android、Windows 和 macOS。

View File

@@ -33,7 +33,7 @@ No authentication required if empty.
#### set_system_proxy
!!! quote ""
!!! error ""
Only supported on Linux, Android, Windows, and macOS.

View File

@@ -33,7 +33,7 @@ SOCKS 和 HTTP 用户
#### set_system_proxy
!!! quote ""
!!! error ""
仅支持 Linux、Android、Windows 和 macOS。

View File

@@ -1,4 +1,4 @@
!!! quote ""
!!! error ""
Only supported on Linux and macOS.

View File

@@ -1,4 +1,4 @@
!!! quote ""
!!! error ""
仅支持 Linux 和 macOS。

View File

@@ -1,4 +1,4 @@
!!! quote ""
!!! error ""
Only supported on Linux.

View File

@@ -1,4 +1,4 @@
!!! quote ""
!!! error ""
仅支持 Linux。

View File

@@ -47,7 +47,7 @@ TLS configuration, see [TLS](/configuration/shared/tls/#inbound).
#### fallback
!!! quote ""
!!! error ""
There is no evidence that GFW detects and blocks Trojan servers based on HTTP responses, and opening the standard http/s port on the server is a much bigger signature.

View File

@@ -49,7 +49,7 @@ TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
#### fallback
!!! quote ""
!!! error ""
没有证据表明 GFW 基于 HTTP 响应检测并阻止 Trojan 服务器,并且在服务器上打开标准 http/s 端口是一个更大的特征。

View File

@@ -1,4 +1,4 @@
!!! quote ""
!!! error ""
Only supported on Linux, Windows and macOS.
@@ -102,7 +102,7 @@ The maximum transmission unit.
Set the default route to the Tun.
!!! quote ""
!!! error ""
To avoid traffic loopback, set `route.auto_detect_interface` or `route.default_interface` or `outbound.bind_interface`
@@ -175,7 +175,7 @@ TCP/IP stack.
#### include_interface
!!! quote ""
!!! error ""
Interface rules are only supported on Linux and require auto_route.
@@ -191,7 +191,7 @@ Conflict with `include_interface`.
#### include_uid
!!! quote ""
!!! error ""
UID rules are only supported on Linux and require auto_route.
@@ -211,7 +211,7 @@ Exclude users in route, but in range.
#### include_android_user
!!! quote ""
!!! error ""
Android user and package rules are only supported on Android and require auto_route.

View File

@@ -1,4 +1,4 @@
!!! quote ""
!!! error ""
仅支持 Linux、Windows 和 macOS。
@@ -102,7 +102,7 @@ tun 接口的 IPv6 前缀。
设置到 Tun 的默认路由。
!!! quote ""
!!! error ""
为避免流量环回,请设置 `route.auto_detect_interface``route.default_interface``outbound.bind_interface`
@@ -171,7 +171,7 @@ TCP/IP 栈。
#### include_interface
!!! quote ""
!!! error ""
接口规则仅在 Linux 下被支持,并且需要 `auto_route`
@@ -187,7 +187,7 @@ TCP/IP 栈。
#### include_uid
!!! quote ""
!!! error ""
UID 规则仅在 Linux 下被支持,并且需要 `auto_route`
@@ -207,7 +207,7 @@ TCP/IP 栈。
#### include_android_user
!!! quote ""
!!! error ""
Android 用户和应用规则仅在 Android 下被支持,并且需要 `auto_route`

View File

@@ -15,7 +15,7 @@
}
```
!!! quote ""
!!! error ""
The selector can only be controlled through the [Clash API](/configuration/experimental#clash-api-fields) currently.

View File

@@ -15,7 +15,7 @@
}
```
!!! quote ""
!!! error ""
选择器目前只能通过 [Clash API](/zh/configuration/experimental#clash-api) 来控制。

View File

@@ -31,7 +31,7 @@ Default outbound tag. the first outbound will be used if empty.
#### auto_detect_interface
!!! quote ""
!!! error ""
Only supported on Linux, Windows and macOS.
@@ -41,7 +41,7 @@ Takes no effect if `outbound.bind_interface` is set.
#### override_android_vpn
!!! quote ""
!!! error ""
Only supported on Android.
@@ -49,7 +49,7 @@ Accept Android VPN as upstream NIC when `auto_detect_interface` enabled.
#### default_interface
!!! quote ""
!!! error ""
Only supported on Linux, Windows and macOS.
@@ -59,7 +59,7 @@ Takes no effect if `auto_detect_interface` is set.
#### default_mark
!!! quote ""
!!! error ""
Only supported on Linux.

View File

@@ -32,7 +32,7 @@
#### auto_detect_interface
!!! quote ""
!!! error ""
仅支持 Linux、Windows 和 macOS。
@@ -42,7 +42,7 @@
#### override_android_vpn
!!! quote ""
!!! error ""
仅支持 Android。
@@ -50,7 +50,7 @@
#### default_interface
!!! quote ""
!!! error ""
仅支持 Linux、Windows 和 macOS。
@@ -60,7 +60,7 @@
#### default_mark
!!! quote ""
!!! error ""
仅支持 Linux。

View File

@@ -83,12 +83,6 @@
1000
],
"clash_mode": "direct",
"wifi_ssid": [
"My WIFI"
],
"wifi_bssid": [
"00:00:00:00:00:00"
],
"invert": false,
"outbound": "direct"
},
@@ -196,7 +190,7 @@ Match port range.
#### process_name
!!! quote ""
!!! error ""
Only supported on Linux, Windows, and macOS.
@@ -204,7 +198,7 @@ Match process name.
#### process_path
!!! quote ""
!!! error ""
Only supported on Linux, Windows, and macOS.
@@ -216,7 +210,7 @@ Match android package name.
#### user
!!! quote ""
!!! error ""
Only supported on Linux.
@@ -224,7 +218,7 @@ Match user name.
#### user_id
!!! quote ""
!!! error ""
Only supported on Linux.
@@ -234,22 +228,6 @@ Match user id.
Match Clash mode.
#### wifi_ssid
!!! quote ""
Only supported in graphical clients on Android and iOS.
Match WiFi SSID.
#### wifi_bssid
!!! quote ""
Only supported in graphical clients on Android and iOS.
Match WiFi BSSID.
#### invert
Invert match result.

View File

@@ -81,12 +81,6 @@
1000
],
"clash_mode": "direct",
"wifi_ssid": [
"My WIFI"
],
"wifi_bssid": [
"00:00:00:00:00:00"
],
"invert": false,
"outbound": "direct"
},
@@ -194,7 +188,7 @@
#### process_name
!!! quote ""
!!! error ""
仅支持 Linux、Windows 和 macOS。
@@ -202,7 +196,7 @@
#### process_path
!!! quote ""
!!! error ""
仅支持 Linux、Windows 和 macOS.
@@ -214,7 +208,7 @@
#### user
!!! quote ""
!!! error ""
仅支持 Linux.
@@ -222,7 +216,7 @@
#### user_id
!!! quote ""
!!! error ""
仅支持 Linux.
@@ -232,22 +226,6 @@
匹配 Clash 模式。
#### wifi_ssid
!!! quote ""
仅在 Android 与 iOS 的图形客户端中支持。
匹配 WiFi SSID。
#### wifi_bssid
!!! quote ""
仅在 Android 与 iOS 的图形客户端中支持。
匹配 WiFi BSSID。
#### invert
反选匹配结果。

View File

@@ -41,7 +41,7 @@ The IPv6 address to bind to.
#### routing_mark
!!! quote ""
!!! error ""
Only supported on Linux.

View File

@@ -44,7 +44,7 @@
#### routing_mark
!!! quote ""
!!! error ""
仅支持 Linux。

View File

@@ -1,8 +1,4 @@
---
icon: material/delete-alert
---
# Deprecated Feature List
# :material-delete-alert: Deprecated Feature List
### 1.6.0

View File

@@ -1,8 +1,4 @@
---
icon: material/delete-alert
---
# 废弃功能列表
# :material-delete-alert: 废弃功能列表
### 1.6.0

View File

@@ -1,8 +1,4 @@
---
icon: material/file-code
---
# Build from source
# :material-file-code: Build from source
## :material-graph: Requirements

View File

@@ -1,8 +1,4 @@
---
icon: material/docker
---
# Docker
# :material-docker: Docker
## :material-console: Command

View File

@@ -1,8 +1,4 @@
---
icon: material/package
---
# Package Manager
# :material-package: Package Manager
## :material-download-box: Manual Installation
@@ -55,36 +51,12 @@ icon: material/package
|------------|--------------------|---------------------|------------------------------|---------------------|
| Termux | Android | [sing-box][termux] | `pkg add sing-box` | :material-check: |
## :material-book-multiple: Service Management
For Linux systems with [systemd][systemd], usually the installation already includes a sing-box service,
you can manage the service using the following command:
| Operation | Command |
|-----------|-----------------------------------------------|
| Enable | `sudo systemctl enable sing-box` |
| Disable | `sudo systemctl disable sing-box` |
| Start | `sudo systemctl start sing-box` |
| Stop | `sudo systemctl stop sing-box` |
| Kill | `sudo systemctl kill sing-box` |
| Restart | `sudo systemctl restart sing-box` |
| Logs | `sudo journalctl -u sing-box --output cat -e` |
| New Logs | `sudo journalctl -u sing-box --output cat -f` |
[alpine]: https://pkgs.alpinelinux.org/packages?name=sing-box
[aur]: https://aur.archlinux.org/packages/sing-box
[nixpkgs]: https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/tools/networking/sing-box/default.nix
[termux]: https://github.com/termux/termux-packages/tree/master/packages/sing-box
[brew]: https://formulae.brew.sh/formula/sing-box
[choco]: https://chocolatey.org/packages/sing-box
[scoop]: https://github.com/ScoopInstaller/Main/blob/master/bucket/sing-box.json
[winget]: https://github.com/microsoft/winget-pkgs/tree/master/manifests/s/SagerNet/sing-box
[systemd]: https://systemd.io/
[winget]: https://github.com/microsoft/winget-pkgs/tree/master/manifests/s/SagerNet/sing-box

View File

@@ -1,8 +1,4 @@
---
icon: material/lightning-bolt
---
# Hysteria 2
# :material-lightning-bolt: Hysteria 2
The most popular Chinese-made simple protocol based on QUIC, the selling point is Brutal,
a congestion control algorithm that can resist packet loss by manually specifying the required rate by the user.
@@ -17,9 +13,9 @@ a congestion control algorithm that can resist packet loss by manually specifyin
## :material-text-box-check: Password Generator
| Generate Password | Action |
|----------------------------|-----------------------------------------------------------------|
| <code id="password"><code> | <button class="md-button" onclick="generate()">Refresh</button> |
| Generate Password | Action |
|----------------------------|-----------------------------------------------|
| <code id="password"><code> | <button onclick="generate()">Refresh</button> |
<script>
function generate() {

View File

@@ -1,8 +1,4 @@
---
icon: material/send
---
# Shadowsocks
# :material-send: Shadowsocks
As the most well-known Chinese-made proxy protocol,
Shadowsocks exists in multiple versions,
@@ -16,9 +12,10 @@ but only AEAD 2022 ciphers TCP with multiplexing is recommended.
## :material-text-box-check: Password Generator
| For `2022-blake3-aes-128-gcm` cipher | For other ciphers | Action |
|--------------------------------------|-------------------------------|-----------------------------------------------------------------|
| <code id="password_16"><code> | <code id="password_32"><code> | <button class="md-button" onclick="generate()">Refresh</button> |
| For `2022-blake3-aes-128-gcm` cipher | For other ciphers | Action |
|--------------------------------------|-------------------------------|-----------------------------------------------|
| <code id="password_16"><code> | <code id="password_32"><code> | <button onclick="generate()">Refresh</button> |
<script>
function generatePassword(element, length) {

View File

@@ -1,8 +1,4 @@
---
icon: material/horse
---
# Trojan
# :material-horse: Trojan
As the most commonly used TLS proxy made in China, Trojan can be used in various combinations,
but only the combination of uTLS and multiplexing is recommended.
@@ -16,9 +12,9 @@ but only the combination of uTLS and multiplexing is recommended.
## :material-text-box-check: Password Generator
| Generate Password | Action |
|----------------------------|-----------------------------------------------------------------|
| <code id="password"><code> | <button class="md-button" onclick="generate()">Refresh</button> |
| Generate Password | Action |
|----------------------------|-----------------------------------------------|
| <code id="password"><code> | <button onclick="generate()">Refresh</button> |
<script>
function generate() {

View File

@@ -1,8 +1,4 @@
---
icon: material/alpha-t-box
---
# TUIC
# :material-alpha-t-box: TUIC
A recently popular Chinese-made simple protocol based on QUIC, the selling point is the BBR congestion control algorithm.
@@ -12,13 +8,13 @@ A recently popular Chinese-made simple protocol based on QUIC, the selling point
| Specification | Binary Characteristics | Active Detect Hiddenness |
|-----------------------------------------------------------|------------------------|--------------------------|
| [GitHub](https://github.com/EAimTY/tuic/blob/dev/SPEC.md) | :material-alert: | :material-check: |
| [Github](https://github.com/EAimTY/tuic/blob/dev/SPEC.md) | :material-alert: | :material-check: |
## Password Generator
| Generated UUID | Generated Password | Action |
|------------------------|----------------------------|-----------------------------------------------------------------|
| <code id="uuid"><code> | <code id="password"><code> | <button class="md-button" onclick="generate()">Refresh</button> |
| Generated UUID | Generated Password | Action |
|------------------------|----------------------------|-----------------------------------------------|
| <code id="uuid"><code> | <code id="password"><code> | <button onclick="generate()">Refresh</button> |
<script>
function generateUUID() {

View File

@@ -1,17 +1,13 @@
---
icon: material/cellphone-link
---
# :material-cellphone-link: Client
# Client
### :material-ray-start: Introduction
## :material-ray-start: Introduction
For a long time, the modern usage and principles of proxy clients
for graphical operating systems have not been clearly described.
However, we can categorize them into three types:
system proxy, firewall redirection, and virtual interface.
### :material-web-refresh: System Proxy
## :material-web-refresh: System Proxy
Almost all graphical environments support system-level proxies,
which are essentially ordinary HTTP proxies that only support TCP.
@@ -38,7 +34,7 @@ flowchart LR
udp[UDP packet] --> leak
```
### :material-wall-fire: Firewall Redirection
## :material-wall-fire: Firewall Redirection
This type of usage typically relies on the firewall or hook interface provided by the operating system,
such as Windows WFP, Linuxs redirect, TProxy and eBPF, and macOSs pf.
@@ -46,7 +42,7 @@ Although it is intrusive and cumbersome to configure,
it remains popular within the community of amateur proxy open source projects like V2Ray,
due to the low technical requirements it imposes on the software.
### :material-expansion-card: Virtual Interface
## :material-expansion-card: Virtual Interface
All L2/L3 proxies (seriously defined VPNs, such as OpenVPN, WireGuard) are based on virtual network interfaces,
which is also the only way for all L4 proxies to work as VPNs on mobile platforms like Android, iOS.
@@ -70,7 +66,7 @@ flowchart TB
assemble --> conn[TCP and UDP connections]
conn --> router[sing-box Router]
router --> direct[Direct outbound]
router --> proxy[Proxy outbounds]
router --> proxy[Proxy outbounds]
router -- DNS hijack --> dns_out[DNS outbound]
dns_out --> dns_router[DNS router]
dns_router --> router
@@ -80,346 +76,4 @@ flowchart TB
default --> destination[Destination server]
default --> proxy_server[Proxy server]
proxy_server --> destination
```
## :material-cellphone-link: Examples
### Basic TUN usage for Chinese users
=== ":material-numeric-4-box: IPv4 only"
```json
{
"dns": {
"servers": [
{
"tag": "google",
"address": "tls://8.8.8.8"
},
{
"tag": "local",
"address": "223.5.5.5",
"detour": "direct"
}
],
"rules": [
{
"outbound": "any",
"server": "local"
}
],
"strategy": "ipv4_only"
},
"inbounds": [
{
"type": "tun",
"inet4_address": "172.19.0.1/30",
"auto_route": true,
"strict_route": false
}
],
"outbounds": [
// ...
{
"type": "direct",
"tag": "direct"
},
{
"type": "dns",
"tag": "dns-out"
}
],
"route": {
"rules": [
{
"protocol": "dns",
"outbound": "dns-out"
},
{
"geoip": [
"private"
],
"outbound": "direct"
}
],
"auto_detect_interface": true
}
}
```
=== ":material-numeric-6-box: IPv4 & IPv6"
```json
{
"dns": {
"servers": [
{
"tag": "google",
"address": "tls://8.8.8.8"
},
{
"tag": "local",
"address": "223.5.5.5",
"detour": "direct"
}
],
"rules": [
{
"outbound": "any",
"server": "local"
}
]
},
"inbounds": [
{
"type": "tun",
"inet4_address": "172.19.0.1/30",
"inet6_address": "fdfe:dcba:9876::1/126",
"auto_route": true,
"strict_route": false
}
],
"outbounds": [
// ...
{
"type": "direct",
"tag": "direct"
},
{
"type": "dns",
"tag": "dns-out"
}
],
"route": {
"rules": [
{
"protocol": "dns",
"outbound": "dns-out"
},
{
"geoip": [
"private"
],
"outbound": "direct"
}
],
"auto_detect_interface": true
}
}
```
=== ":material-domain-switch: FakeIP"
```json
{
"dns": {
"servers": [
{
"tag": "google",
"address": "tls://8.8.8.8"
},
{
"tag": "local",
"address": "223.5.5.5",
"detour": "direct"
},
{
"tag": "remote",
"address": "fakeip"
}
],
"rules": [
{
"outbound": "any",
"server": "local"
},
{
"query_type": [
"A",
"AAAA"
],
"server": "remote"
}
],
"fakeip": {
"enabled": true,
"inet4_range": "198.18.0.0/15",
"inet6_range": "fc00::/18"
},
"independent_cache": true
},
"inbounds": [
{
"type": "tun",
"inet4_address": "172.19.0.1/30",
"inet6_address": "fdfe:dcba:9876::1/126",
"auto_route": true,
"strict_route": true
}
],
"outbounds": [
// ...
{
"type": "direct",
"tag": "direct"
},
{
"type": "dns",
"tag": "dns-out"
}
],
"route": {
"rules": [
{
"protocol": "dns",
"outbound": "dns-out"
},
{
"geoip": [
"private"
],
"outbound": "direct"
}
],
"auto_detect_interface": true
}
}
```
### Traffic bypass usage for Chinese users
=== ":material-dns: DNS rules"
!!! info
DNS rules are optional if FakeIP is used.
```json
{
"dns": {
"servers": [
{
"tag": "google",
"address": "tls://8.8.8.8"
},
{
"tag": "local",
"address": "223.5.5.5",
"detour": "direct"
}
],
"rules": [
{
"outbound": "any",
"server": "local"
},
{
"clash_mode": "Direct",
"server": "local"
},
{
"clash_mode": "Global",
"server": "google"
},
{
"type": "logical",
"mode": "and",
"rules": [
{
"geosite": "geolocation-!cn",
"invert": true
},
{
"geosite": [
"cn",
"category-companies@cn"
],
}
],
"server": "local"
}
]
}
}
```
=== ":material-router-network: Route rules"
```json
{
"outbounds": [
{
"type": "direct",
"tag": "direct"
},
{
"type": "block",
"tag": "block"
}
],
"route": {
"rules": [
{
"type": "logical",
"mode": "or",
"rules": [
{
"protocol": "dns"
},
{
"port": 53
}
],
"outbound": "dns"
},
{
"geoip": "private",
"outbound": "direct"
},
{
"clash_mode": "Direct",
"outbound": "direct"
},
{
"clash_mode": "Global",
"outbound": "default"
},
{
"type": "logical",
"mode": "or",
"rules": [
{
"port": 853
},
{
"network": "udp",
"port": 443
},
{
"protocol": "stun"
}
],
"outbound": "block"
},
{
"type": "logical",
"mode": "and",
"rules": [
{
"geosite": "geolocation-!cn",
"invert": true
},
{
"geosite": [
"cn",
"category-companies@cn"
],
"geoip": "cn"
}
],
"outbound": "direct"
}
]
}
}
```
```

View File

@@ -1,8 +1,4 @@
---
icon: material/server
---
# Server
# :material-server: Server
To use sing-box as a proxy protocol server, you pretty much only need to configure the inbound for that protocol.

66
docs/manual/proxy/tun.md Normal file
View File

@@ -0,0 +1,66 @@
# :material-expansion-card: TUN
## :material-text-box: Definition
Refers to TUNnel, a virtual network device supported by the kernel.
Its also used in sing-box to denote the extensive functionality surrounding TUN inbound:
including traffic assembly, automatic routing, and network and default interface monitoring.
The following flow chart describes the minimal TUN-based transparent proxy process in sing-box:
``` mermaid
flowchart LR
subgraph inbound [Inbound]
direction TB
packet[IP Packet]
packet --> windows[Windows / macOS]
packet --> linux[Linux]
tun[TUN interface]
windows -. route .-> tun
linux -. iproute2 route/rule .-> tun
tun --> gvisor[gVisor TUN stack]
tun --> system[system TUN stack]
assemble([L3 to L4 assemble])
gvisor --> assemble
system --> assemble
assemble --> conn[TCP and UDP connections]
conn --> router[sing-box Router]
end
subgraph outbound [Outbound]
direction TB
direct[Direct outbound]
proxy[Proxy outbounds]
direct --> adi([auto detect interface])
proxy --> adi
adi --> default[Default network interface in the system]
default --> destination[Destination server]
default --> proxy_server[Proxy server]
proxy_server --> destination
end
inbound --> outbound
```
## :material-help-box: How to
A basic TUN-based transparent proxy configuration file includes: an TUN inbound, `route.auto_detect_interface`, like:
```json
{
"inbounds": [
{
"type": "tun",
"inet4_address": "172.19.0.1/30",
"inet6_address": "fdfe:dcba:9876::1/126",
"auto_route": true,
"strict_route": true
}
],
"route": {
"auto_detect_interface": true
}
}
```
TODO: finish this wiki

View File

@@ -1,13 +1,9 @@
---
icon: material/forum
---
# Support
# :material-forum: Support
| Channel | Link |
|:------------------------------|:--------------------------------------------|
| Community | https://community.sagernet.org |
| GitHub Issues | https://github.com/SagerNet/sing-box/issues |
| Github Issues | https://github.com/SagerNet/sing-box/issues |
| Telegram notification channel | https://t.me/yapnc |
| Telegram user group | https://t.me/yapug |
| Email | contact@sagernet.org |

View File

@@ -1,13 +1,9 @@
---
icon: material/forum
---
# 支持
# :material-forum: 支持
| 通道 | 链接 |
|:--------------|:--------------------------------------------|
| 社区 | https://community.sagernet.org |
| GitHub Issues | https://github.com/SagerNet/sing-box/issues |
| Github Issues | https://github.com/SagerNet/sing-box/issues |
| Telegram 通知频道 | https://t.me/yapnc |
| Telegram 用户组 | https://t.me/yapug |
| 邮件 | contact@sagernet.org |

View File

@@ -83,7 +83,7 @@ func getGroupDelay(server *Server) func(w http.ResponseWriter, r *http.Request)
var result map[string]uint16
if urlTestGroup, isURLTestGroup := group.(adapter.URLTestGroup); isURLTestGroup {
result, err = urlTestGroup.URLTest(ctx)
result, err = urlTestGroup.URLTest(ctx, url)
} else {
outbounds := common.FilterNotNil(common.Map(group.All(), func(it string) adapter.Outbound {
itOutbound, _ := server.router.Outbound(it)

View File

@@ -1,7 +1,6 @@
package cachefile
import (
"context"
"errors"
"net/netip"
"os"
@@ -14,7 +13,6 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/service/filemanager"
)
var (
@@ -43,7 +41,7 @@ type CacheFile struct {
saveMetadataTimer *time.Timer
}
func Open(ctx context.Context, path string, cacheID string) (*CacheFile, error) {
func Open(path string, cacheID string) (*CacheFile, error) {
const fileMode = 0o666
options := bbolt.Options{Timeout: time.Second}
var (
@@ -69,10 +67,6 @@ func Open(ctx context.Context, path string, cacheID string) (*CacheFile, error)
if err != nil {
return nil, err
}
err = filemanager.Chown(ctx, path)
if err != nil {
return nil, E.Cause(err, "platform chown")
}
var cacheIDBytes []byte
if cacheID != "" {
cacheIDBytes = append([]byte{0}, []byte(cacheID)...)

View File

@@ -148,7 +148,7 @@ func NewServer(ctx context.Context, router adapter.Router, logFactory log.Observ
func (s *Server) PreStart() error {
if s.cacheFilePath != "" {
cacheFile, err := cachefile.Open(s.ctx, s.cacheFilePath, s.cacheID)
cacheFile, err := cachefile.Open(s.cacheFilePath, s.cacheID)
if err != nil {
return E.Cause(err, "open cache file")
}

View File

@@ -70,6 +70,9 @@ func (m *Manager) Snapshot() *Snapshot {
return true
})
//if memoryInfo, err := m.process.MemoryInfo(); err == nil {
// m.memory = memoryInfo.RSS
//} else {
var memStats runtime.MemStats
runtime.ReadMemStats(&memStats)
m.memory = memStats.StackInuse + memStats.HeapInuse + memStats.HeapIdle - memStats.HeapReleased

View File

@@ -14,6 +14,7 @@ import (
type StatusMessage struct {
Memory int64
MemoryInuse int64
Goroutines int32
ConnectionsIn int32
ConnectionsOut int32

View File

@@ -19,7 +19,6 @@ type PlatformInterface interface {
UsePlatformInterfaceGetter() bool
GetInterfaces() (NetworkInterfaceIterator, error)
UnderNetworkExtension() bool
ReadWIFIState() *WIFIState
ClearDNSCache()
}
@@ -39,15 +38,6 @@ type NetworkInterface struct {
Addresses StringIterator
}
type WIFIState struct {
SSID string
BSSID string
}
func NewWIFIState(wifiSSID string, wifiBSSID string) *WIFIState {
return &WIFIState{wifiSSID, wifiBSSID}
}
type NetworkInterfaceIterator interface {
Next() *NetworkInterface
HasNext() bool

View File

@@ -23,7 +23,6 @@ type Interface interface {
Interfaces() ([]NetworkInterface, error)
UnderNetworkExtension() bool
ClearDNSCache()
ReadWIFIState() adapter.WIFIState
process.Searcher
}

View File

@@ -210,14 +210,6 @@ func (w *platformInterfaceWrapper) ClearDNSCache() {
w.iif.ClearDNSCache()
}
func (w *platformInterfaceWrapper) ReadWIFIState() adapter.WIFIState {
wifiState := w.iif.ReadWIFIState()
if wifiState == nil {
return adapter.WIFIState{}
}
return (adapter.WIFIState)(*wifiState)
}
func (w *platformInterfaceWrapper) DisableColors() bool {
return runtime.GOOS != "android"
}

38
go.mod
View File

@@ -4,7 +4,7 @@ go 1.20
require (
berty.tech/go-libtor v1.0.385
github.com/caddyserver/certmagic v0.20.0
github.com/caddyserver/certmagic v0.19.2
github.com/cloudflare/circl v1.3.6
github.com/cretz/bine v0.2.0
github.com/fsnotify/fsnotify v1.7.0
@@ -12,45 +12,45 @@ require (
github.com/go-chi/cors v1.2.1
github.com/go-chi/render v1.0.3
github.com/gofrs/uuid/v5 v5.0.0
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2
github.com/insomniacslk/dhcp v0.0.0-20231016090811-6a2c8fbdcc1c
github.com/libdns/alidns v1.0.3
github.com/libdns/cloudflare v0.1.0
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/mholt/acmez v1.2.0
github.com/miekg/dns v1.1.57
github.com/miekg/dns v1.1.56
github.com/ooni/go-libtor v1.1.8
github.com/oschwald/maxminddb-golang v1.12.0
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
github.com/sagernet/cloudflare-tls v0.0.0-20230829051644-4a68352d0c4a
github.com/sagernet/gomobile v0.0.0-20230915142329-c6740b6d2950
github.com/sagernet/gvisor v0.0.0-20231119034329-07cfb6aaf930
github.com/sagernet/gvisor v0.0.0-20230930141345-5fef6f2e17ab
github.com/sagernet/quic-go v0.40.0
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
github.com/sagernet/sing v0.2.19-0.20231208031707-0830d1517da8
github.com/sagernet/sing-dns v0.1.11
github.com/sagernet/sing-mux v0.1.5
github.com/sagernet/sing-quic v0.1.5
github.com/sagernet/sing v0.2.18-0.20231108041402-4fbbd193203c
github.com/sagernet/sing-dns v0.1.11-0.20231116102430-5a2133f5d358
github.com/sagernet/sing-mux v0.1.5-0.20231109075101-6b086ed6bb07
github.com/sagernet/sing-quic v0.1.4-0.20231114135334-e2a6aab55cca
github.com/sagernet/sing-shadowsocks v0.2.5
github.com/sagernet/sing-shadowsocks2 v0.1.5
github.com/sagernet/sing-shadowsocks2 v0.1.4
github.com/sagernet/sing-shadowtls v0.1.4
github.com/sagernet/sing-tun v0.1.22
github.com/sagernet/sing-tun v0.1.20-0.20231116102736-3fa4ee409a9d
github.com/sagernet/sing-vmess v0.1.8
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2
github.com/sagernet/wireguard-go v0.0.0-20230807125731-5d4a7ef2dc5f
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854
github.com/sagernet/ws v0.0.0-20231030053741-7d481eb31bed
github.com/spf13/cobra v1.8.0
github.com/stretchr/testify v1.8.4
go.uber.org/zap v1.26.0
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
golang.org/x/crypto v0.16.0
golang.org/x/net v0.19.0
golang.org/x/sys v0.15.0
go4.org/netipx v0.0.0-20230824141953-6213f710f925
golang.org/x/crypto v0.15.0
golang.org/x/net v0.18.0
golang.org/x/sys v0.14.0
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
google.golang.org/grpc v1.59.0
google.golang.org/protobuf v1.31.0
howett.net/plist v1.0.1
howett.net/plist v1.0.0
)
//replace github.com/sagernet/sing => ../sing
@@ -86,11 +86,11 @@ require (
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.4.0 // indirect
golang.org/x/tools v0.16.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.15.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

78
go.sum
View File

@@ -4,8 +4,8 @@ github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/caddyserver/certmagic v0.20.0 h1:bTw7LcEZAh9ucYCRXyCpIrSAGplplI0vGYJ4BpCQ/Fc=
github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg=
github.com/caddyserver/certmagic v0.19.2 h1:HZd1AKLx4592MalEGQS39DKs2ZOAJCEM/xYPMQ2/ui0=
github.com/caddyserver/certmagic v0.19.2/go.mod h1:fsL01NomQ6N+kE2j37ZCnig2MFosG+MIO4ztnmG/zz8=
github.com/cloudflare/circl v1.3.6 h1:/xbKIqSHbZXHwkhbrhrt2YOHIwYJlXH94E3tI/gDlUg=
github.com/cloudflare/circl v1.3.6/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@@ -47,8 +47,8 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 h1:9K06NfxkBh25x56yVhWWlKFE8YpicaSfHwoV8SFbueA=
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2/go.mod h1:3A9PQ1cunSDF/1rbTq99Ts4pVnycWg+vlPkfeD2NLFI=
github.com/insomniacslk/dhcp v0.0.0-20231016090811-6a2c8fbdcc1c h1:PgxFEySCI41sH0mB7/2XswdXbUykQsRUGod8Rn+NubM=
github.com/insomniacslk/dhcp v0.0.0-20231016090811-6a2c8fbdcc1c/go.mod h1:3A9PQ1cunSDF/1rbTq99Ts4pVnycWg+vlPkfeD2NLFI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
@@ -72,8 +72,8 @@ github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczG
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss=
@@ -100,8 +100,8 @@ github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms=
github.com/sagernet/gomobile v0.0.0-20230915142329-c6740b6d2950 h1:hUz/2mJLgi7l2H36JGpDY+jou9FmI6kAm0ZkU+xPpgE=
github.com/sagernet/gomobile v0.0.0-20230915142329-c6740b6d2950/go.mod h1:5YE39YkJkCcMsfq1jMKkjsrM2GfBoF9JVWnvU89hmvU=
github.com/sagernet/gvisor v0.0.0-20231119034329-07cfb6aaf930 h1:dSPgjIw0CT6ISLeEh8Q20dZMBMFCcEceo23+LncRcNQ=
github.com/sagernet/gvisor v0.0.0-20231119034329-07cfb6aaf930/go.mod h1:JpKHkOYgh4wLwrX2BhH3ZIvCvazCkTnPeEcmigZJfHY=
github.com/sagernet/gvisor v0.0.0-20230930141345-5fef6f2e17ab h1:u+xQoi/Yc6bNUvTfrDD6HhGRybn2lzrhf5vmS+wb4Ho=
github.com/sagernet/gvisor v0.0.0-20230930141345-5fef6f2e17ab/go.mod h1:3akUhSHSVtLuJaYcW5JPepUraBOW06Ibz2HKwaK5rOk=
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.40.0 h1:DvQNPb72lzvNQDe9tcUyHTw8eRv6PLtM2mNYmdlzUMo=
@@ -110,22 +110,22 @@ github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byL
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.19-0.20231208031707-0830d1517da8 h1:w9gxEZISgkLf1VCySAu4ao7Ptgbkjl3t5JosaDAhqRE=
github.com/sagernet/sing v0.2.19-0.20231208031707-0830d1517da8/go.mod h1:Ce5LNojQOgOiWhiD8pPD6E9H7e2KgtOe3Zxx4Ou5u80=
github.com/sagernet/sing-dns v0.1.11 h1:PPrMCVVrAeR3f5X23I+cmvacXJ+kzuyAsBiWyUKhGSE=
github.com/sagernet/sing-dns v0.1.11/go.mod h1:zJ/YjnYB61SYE+ubMcMqVdpaSvsyQ2iShQGO3vuLvvE=
github.com/sagernet/sing-mux v0.1.5 h1:jUbYth9QQd1wsDmU8Ush+fKce7lNo9TMv2dp8PJtSOY=
github.com/sagernet/sing-mux v0.1.5/go.mod h1:MoH6Soz1R+CYZcCeIXZWx6fkZa6hQc9o3HZu9G6CDTw=
github.com/sagernet/sing-quic v0.1.5 h1:PIQzE4cGrry+JkkMEJH/EH3wRkv/QgD48+ScNr/2oig=
github.com/sagernet/sing-quic v0.1.5/go.mod h1:n2mXukpubasyV4SlWyyW0+LCdAn7DZ8/brAkUxZujrw=
github.com/sagernet/sing v0.2.18-0.20231108041402-4fbbd193203c h1:uask61Pxc3nGqsOSjqnBKrwfODWRoEa80lXm04LNk0E=
github.com/sagernet/sing v0.2.18-0.20231108041402-4fbbd193203c/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
github.com/sagernet/sing-dns v0.1.11-0.20231116102430-5a2133f5d358 h1:psJQg/KXVQTupFFR1liaCAucW+NwCDhe1oYfkmz8EJ8=
github.com/sagernet/sing-dns v0.1.11-0.20231116102430-5a2133f5d358/go.mod h1:vtUimtf7Nq9EdvD5WTpfCr69KL1M7bcgOVKiYBiAY/c=
github.com/sagernet/sing-mux v0.1.5-0.20231109075101-6b086ed6bb07 h1:ncKb5tVOsCQgCsv6UpsA0jinbNb5OQ5GMPJlyQP3EHM=
github.com/sagernet/sing-mux v0.1.5-0.20231109075101-6b086ed6bb07/go.mod h1:u/MZf32xPG8jEKe3t+xUV67EBnKtDtCaPhsJQOQGUYU=
github.com/sagernet/sing-quic v0.1.4-0.20231114135334-e2a6aab55cca h1:wGQhe7D8Y4D3lPK8Obtv4IQAvnkEKMMu8Uv/BiYpyWc=
github.com/sagernet/sing-quic v0.1.4-0.20231114135334-e2a6aab55cca/go.mod h1:B6OgRz+qLn3N1114dcZVExkdarArtsAX2MgWJIfB72c=
github.com/sagernet/sing-shadowsocks v0.2.5 h1:qxIttos4xu6ii7MTVJYA8EFQR7Q3KG6xMqmLJIFtBaY=
github.com/sagernet/sing-shadowsocks v0.2.5/go.mod h1:MGWGkcU2xW2G2mfArT9/QqpVLOGU+dBaahZCtPHdt7A=
github.com/sagernet/sing-shadowsocks2 v0.1.5 h1:JDeAJ4ZWlYZ7F6qEVdDKPhQEangxKw/JtmU+i/YfCYE=
github.com/sagernet/sing-shadowsocks2 v0.1.5/go.mod h1:KF65y8lI5PGHyMgRZGYXYsH9ilgRc/yr+NYbSNGuBm4=
github.com/sagernet/sing-shadowsocks2 v0.1.4 h1:vht2M8t3m5DTgXR2j24KbYOygG5aOp+MUhpQnAux728=
github.com/sagernet/sing-shadowsocks2 v0.1.4/go.mod h1:Mgdee99NxxNd5Zld3ixIs18yVs4x2dI2VTDDE1N14Wc=
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.22 h1:AECJTkiugCK+GCrV41YZ56HB/Z/lDXZvRVas4fNvO30=
github.com/sagernet/sing-tun v0.1.22/go.mod h1:fliIEXDRv2u1uT3uCZIoA1daoZcD4f6TeIuzNIzlsN8=
github.com/sagernet/sing-tun v0.1.20-0.20231116102736-3fa4ee409a9d h1:FlCho4lZEMC6N6dThTVd2rOkWPW0iTqgy7YEAboeyps=
github.com/sagernet/sing-tun v0.1.20-0.20231116102736-3fa4ee409a9d/go.mod h1:B1y93eY/4pNklxrstVGFrDrH4dUZAiZFBQ4MFn6HJXA=
github.com/sagernet/sing-vmess v0.1.8 h1:XVWad1RpTy9b5tPxdm5MCU8cGfrTGdR8qCq6HV2aCNc=
github.com/sagernet/sing-vmess v0.1.8/go.mod h1:vhx32UNzTDUkNwOyIjcZQohre1CaytquC5mPplId8uA=
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as=
@@ -136,8 +136,8 @@ github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 h1:kDUqhc9Vsk5HJuhfI
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2/go.mod h1:JKQMZq/O2qnZjdrt+B57olmfgEmLtY9iiSIEYtWvoSM=
github.com/sagernet/wireguard-go v0.0.0-20230807125731-5d4a7ef2dc5f h1:Kvo8w8Y9lzFGB/7z09MJ3TR99TFtfI/IuY87Ygcycho=
github.com/sagernet/wireguard-go v0.0.0-20230807125731-5d4a7ef2dc5f/go.mod h1:mySs0abhpc/gLlvhoq7HP1RzOaRmIXVeZGCh++zoApk=
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc=
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854/go.mod h1:LtfoSK3+NG57tvnVEHgcuBW9ujgE8enPSgzgwStwCAA=
github.com/sagernet/ws v0.0.0-20231030053741-7d481eb31bed h1:90a510OeE9siSJoYsI8nSjPmA+u5ROMDts/ZkdNsuXY=
github.com/sagernet/ws v0.0.0-20231030053741-7d481eb31bed/go.mod h1:LtfoSK3+NG57tvnVEHgcuBW9ujgE8enPSgzgwStwCAA=
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=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
@@ -165,20 +165,20 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
go4.org/netipx v0.0.0-20230824141953-6213f710f925 h1:eeQDDVKFkx0g4Hyy8pHgmZaK0EqB4SD6rvKbUdN3ziQ=
go4.org/netipx v0.0.0-20230824141953-6213f710f925/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No=
golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -189,19 +189,19 @@ golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBc
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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY=
golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=
golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=
golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=
@@ -220,7 +220,7 @@ gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM=
howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=

View File

@@ -30,7 +30,6 @@ theme:
- navigation.sections
- header.autohide
- content.code.copy
- content.code.select
- content.code.annotate
nav:
- Home:

View File

@@ -33,7 +33,7 @@ type Service struct {
func NewService(ctx context.Context, router adapter.Router, logger logger.Logger, options option.NTPOptions) (*Service, error) {
ctx, cancel := common.ContextWithCancelCause(ctx)
server := M.ParseSocksaddrHostPort(options.Server, options.ServerPort)
server := options.ServerOptions.Build()
if server.Port == 0 {
server.Port = 123
}

View File

@@ -1,10 +1,9 @@
package option
type NTPOptions struct {
Enabled bool `json:"enabled,omitempty"`
Server string `json:"server,omitempty"`
ServerPort uint16 `json:"server_port,omitempty"`
Enabled bool `json:"enabled"`
Interval Duration `json:"interval,omitempty"`
WriteToSystem bool `json:"write_to_system,omitempty"`
ServerOptions
DialerOptions
}

View File

@@ -78,8 +78,6 @@ type DefaultRule struct {
User Listable[string] `json:"user,omitempty"`
UserID Listable[int32] `json:"user_id,omitempty"`
ClashMode string `json:"clash_mode,omitempty"`
WIFISSID Listable[string] `json:"wifi_ssid,omitempty"`
WIFIBSSID Listable[string] `json:"wifi_bssid,omitempty"`
Invert bool `json:"invert,omitempty"`
Outbound string `json:"outbound,omitempty"`
}

View File

@@ -78,8 +78,6 @@ type DefaultDNSRule struct {
UserID Listable[int32] `json:"user_id,omitempty"`
Outbound Listable[string] `json:"outbound,omitempty"`
ClashMode string `json:"clash_mode,omitempty"`
WIFISSID Listable[string] `json:"wifi_ssid,omitempty"`
WIFIBSSID Listable[string] `json:"wifi_bssid,omitempty"`
Invert bool `json:"invert,omitempty"`
Server string `json:"server,omitempty"`
DisableCache bool `json:"disable_cache,omitempty"`

View File

@@ -3,6 +3,7 @@ package outbound
import (
"context"
"net"
"sort"
"sync"
"time"
@@ -82,7 +83,7 @@ func (s *URLTest) Start() error {
}
func (s *URLTest) PostStart() error {
s.group.PostStart()
go s.CheckOutbounds()
return nil
}
@@ -100,8 +101,8 @@ func (s *URLTest) All() []string {
return s.tags
}
func (s *URLTest) URLTest(ctx context.Context) (map[string]uint16, error) {
return s.group.URLTest(ctx)
func (s *URLTest) URLTest(ctx context.Context, link string) (map[string]uint16, error) {
return s.group.URLTest(ctx, link)
}
func (s *URLTest) CheckOutbounds() {
@@ -109,7 +110,7 @@ func (s *URLTest) CheckOutbounds() {
}
func (s *URLTest) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
s.group.Touch()
s.group.Start()
outbound := s.group.Select(network)
conn, err := outbound.DialContext(ctx, network, destination)
if err == nil {
@@ -121,7 +122,7 @@ func (s *URLTest) DialContext(ctx context.Context, network string, destination M
}
func (s *URLTest) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
s.group.Touch()
s.group.Start()
outbound := s.group.Select(N.NetworkUDP)
conn, err := outbound.ListenPacket(ctx, destination)
if err == nil {
@@ -163,11 +164,9 @@ type URLTestGroup struct {
interruptGroup *interrupt.Group
interruptExternalConnections bool
access sync.Mutex
ticker *time.Ticker
close chan struct{}
started bool
lastActive atomic.TypedValue[time.Time]
access sync.Mutex
ticker *time.Ticker
close chan struct{}
}
func NewURLTestGroup(
@@ -209,18 +208,8 @@ func NewURLTestGroup(
}
}
func (g *URLTestGroup) PostStart() {
g.started = true
g.lastActive.Store(time.Now())
go g.CheckOutbounds(false)
}
func (g *URLTestGroup) Touch() {
if !g.started {
return
}
func (g *URLTestGroup) Start() {
if g.ticker != nil {
g.lastActive.Store(time.Now())
return
}
g.access.Lock()
@@ -271,30 +260,51 @@ func (g *URLTestGroup) Select(network string) adapter.Outbound {
return minOutbound
}
func (g *URLTestGroup) loopCheck() {
if time.Now().Sub(g.lastActive.Load()) > g.interval {
g.CheckOutbounds(false)
func (g *URLTestGroup) Fallback(used adapter.Outbound) []adapter.Outbound {
outbounds := make([]adapter.Outbound, 0, len(g.outbounds)-1)
for _, detour := range g.outbounds {
if detour != used {
outbounds = append(outbounds, detour)
}
}
sort.SliceStable(outbounds, func(i, j int) bool {
oi := outbounds[i]
oj := outbounds[j]
hi := g.history.LoadURLTestHistory(RealTag(oi))
if hi == nil {
return false
}
hj := g.history.LoadURLTestHistory(RealTag(oj))
if hj == nil {
return false
}
return hi.Delay < hj.Delay
})
return outbounds
}
func (g *URLTestGroup) loopCheck() {
go g.CheckOutbounds(true)
for {
g.pauseManager.WaitActive()
select {
case <-g.close:
return
case <-g.ticker.C:
g.CheckOutbounds(false)
}
g.pauseManager.WaitActive()
g.CheckOutbounds(false)
}
}
func (g *URLTestGroup) CheckOutbounds(force bool) {
_, _ = g.urlTest(g.ctx, force)
_, _ = g.urlTest(g.ctx, g.link, force)
}
func (g *URLTestGroup) URLTest(ctx context.Context) (map[string]uint16, error) {
return g.urlTest(ctx, false)
func (g *URLTestGroup) URLTest(ctx context.Context, link string) (map[string]uint16, error) {
return g.urlTest(ctx, link, false)
}
func (g *URLTestGroup) urlTest(ctx context.Context, force bool) (map[string]uint16, error) {
func (g *URLTestGroup) urlTest(ctx context.Context, link string, force bool) (map[string]uint16, error) {
result := make(map[string]uint16)
if g.checking.Swap(true) {
return result, nil
@@ -321,7 +331,7 @@ func (g *URLTestGroup) urlTest(ctx context.Context, force bool) (map[string]uint
b.Go(realTag, func() (any, error) {
ctx, cancel := context.WithTimeout(context.Background(), C.TCPTimeout)
defer cancel()
t, err := urltest.URLTest(ctx, g.link, p)
t, err := urltest.URLTest(ctx, link, p)
if err != nil {
g.logger.Debug("outbound ", tag, " unavailable: ", err)
g.history.DeleteURLTestHistory(realTag)

View File

@@ -86,9 +86,6 @@ type Router struct {
clashServer adapter.ClashServer
v2rayServer adapter.V2RayServer
platformInterface platform.Interface
needWIFIState bool
wifiState adapter.WIFIState
started bool
}
func NewRouter(
@@ -119,7 +116,6 @@ func NewRouter(
defaultMark: options.DefaultMark,
pauseManager: pause.ManagerFromContext(ctx),
platformInterface: platformInterface,
needWIFIState: hasRule(options.Rules, isWIFIRule) || hasDNSRule(dnsOptions.Rules, isWIFIDNSRule),
}
router.dnsClient = dns.NewClient(dns.ClientOptions{
DisableCache: dnsOptions.DNSClientOptions.DisableCache,
@@ -332,11 +328,6 @@ func NewRouter(
service.ContextWith[serviceNTP.TimeService](ctx, timeService)
router.timeService = timeService
}
if platformInterface != nil && router.interfaceMonitor != nil && router.needWIFIState {
router.interfaceMonitor.RegisterCallback(func(_ int) {
router.updateWIFIState()
})
}
return router, nil
}
@@ -477,9 +468,6 @@ func (r *Router) Start() error {
r.geositeCache = nil
r.geositeReader = nil
}
if r.needWIFIState {
r.updateWIFIState()
}
for i, rule := range r.rules {
err := rule.Start()
if err != nil {
@@ -572,11 +560,6 @@ func (r *Router) Close() error {
return err
}
func (r *Router) PostStart() error {
r.started = true
return nil
}
func (r *Router) Outbound(tag string) (adapter.Outbound, bool) {
outbound, loaded := r.outboundByTag[tag]
return outbound, loaded
@@ -957,10 +940,6 @@ func (r *Router) Rules() []adapter.Rule {
return r.rules
}
func (r *Router) WIFIState() adapter.WIFIState {
return r.wifiState
}
func (r *Router) NetworkMonitor() tun.NetworkUpdateMonitor {
return r.networkMonitor
}
@@ -1021,11 +1000,8 @@ func (r *Router) notifyNetworkUpdate(event int) {
}
}
if !r.started {
return
}
_ = r.ResetNetwork()
r.ResetNetwork()
return
}
func (r *Router) ResetNetwork() error {
@@ -1043,14 +1019,3 @@ func (r *Router) ResetNetwork() error {
}
return nil
}
func (r *Router) updateWIFIState() {
if r.platformInterface == nil {
return
}
state := r.platformInterface.ReadWIFIState()
if state != r.wifiState {
r.wifiState = state
r.logger.Info("updated WIFI state: SSID=", state.SSID, ", BSSID=", state.BSSID)
}
}

View File

@@ -307,11 +307,3 @@ func isProcessDNSRule(rule option.DefaultDNSRule) bool {
func notPrivateNode(code string) bool {
return code != "private"
}
func isWIFIRule(rule option.DefaultRule) bool {
return len(rule.WIFISSID) > 0 || len(rule.WIFIBSSID) > 0
}
func isWIFIDNSRule(rule option.DefaultDNSRule) bool {
return len(rule.WIFISSID) > 0 || len(rule.WIFIBSSID) > 0
}

View File

@@ -184,16 +184,6 @@ func NewDefaultRule(router adapter.Router, logger log.ContextLogger, options opt
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.WIFISSID) > 0 {
item := NewWIFISSIDItem(router, options.WIFISSID)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.WIFIBSSID) > 0 {
item := NewWIFIBSSIDItem(router, options.WIFIBSSID)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
return rule, nil
}

View File

@@ -180,16 +180,6 @@ func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.WIFISSID) > 0 {
item := NewWIFISSIDItem(router, options.WIFISSID)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.WIFIBSSID) > 0 {
item := NewWIFIBSSIDItem(router, options.WIFIBSSID)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
return rule, nil
}

View File

@@ -1,39 +0,0 @@
package route
import (
"strings"
"github.com/sagernet/sing-box/adapter"
F "github.com/sagernet/sing/common/format"
)
var _ RuleItem = (*WIFIBSSIDItem)(nil)
type WIFIBSSIDItem struct {
bssidList []string
bssidMap map[string]bool
router adapter.Router
}
func NewWIFIBSSIDItem(router adapter.Router, bssidList []string) *WIFIBSSIDItem {
bssidMap := make(map[string]bool)
for _, bssid := range bssidList {
bssidMap[bssid] = true
}
return &WIFIBSSIDItem{
bssidList,
bssidMap,
router,
}
}
func (r *WIFIBSSIDItem) Match(metadata *adapter.InboundContext) bool {
return r.bssidMap[r.router.WIFIState().BSSID]
}
func (r *WIFIBSSIDItem) String() string {
if len(r.bssidList) == 1 {
return F.ToString("wifi_bssid=", r.bssidList[0])
}
return F.ToString("wifi_bssid=[", strings.Join(r.bssidList, " "), "]")
}

View File

@@ -1,39 +0,0 @@
package route
import (
"strings"
"github.com/sagernet/sing-box/adapter"
F "github.com/sagernet/sing/common/format"
)
var _ RuleItem = (*WIFISSIDItem)(nil)
type WIFISSIDItem struct {
ssidList []string
ssidMap map[string]bool
router adapter.Router
}
func NewWIFISSIDItem(router adapter.Router, ssidList []string) *WIFISSIDItem {
ssidMap := make(map[string]bool)
for _, ssid := range ssidList {
ssidMap[ssid] = true
}
return &WIFISSIDItem{
ssidList,
ssidMap,
router,
}
}
func (r *WIFISSIDItem) Match(metadata *adapter.InboundContext) bool {
return r.ssidMap[r.router.WIFIState().SSID]
}
func (r *WIFISSIDItem) String() string {
if len(r.ssidList) == 1 {
return F.ToString("wifi_ssid=", r.ssidList[0])
}
return F.ToString("wifi_ssid=[", strings.Join(r.ssidList, " "), "]")
}

View File

@@ -11,11 +11,11 @@ require (
github.com/docker/go-connections v0.4.0
github.com/gofrs/uuid/v5 v5.0.0
github.com/sagernet/quic-go v0.0.0-20231008035953-32727fef9460
github.com/sagernet/sing v0.2.18-0.20231119032432-6a556bfa50cc
github.com/sagernet/sing-dns v0.1.11
github.com/sagernet/sing-quic v0.1.4
github.com/sagernet/sing v0.2.18-0.20231108041402-4fbbd193203c
github.com/sagernet/sing-dns v0.1.11-0.20231116102430-5a2133f5d358
github.com/sagernet/sing-quic v0.1.4-0.20231111111624-370e6abf6769
github.com/sagernet/sing-shadowsocks v0.2.5
github.com/sagernet/sing-shadowsocks2 v0.1.5
github.com/sagernet/sing-shadowsocks2 v0.1.4
github.com/spyzhov/ajson v0.9.0
github.com/stretchr/testify v1.8.4
go.uber.org/goleak v1.3.0
@@ -56,7 +56,7 @@ require (
github.com/libdns/libdns v0.2.1 // indirect
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
github.com/mholt/acmez v1.2.0 // indirect
github.com/miekg/dns v1.1.57 // indirect
github.com/miekg/dns v1.1.56 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/onsi/ginkgo/v2 v2.9.5 // indirect
@@ -72,12 +72,12 @@ require (
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a // indirect
github.com/sagernet/cloudflare-tls v0.0.0-20230829051644-4a68352d0c4a // indirect
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect
github.com/sagernet/gvisor v0.0.0-20231119034329-07cfb6aaf930 // indirect
github.com/sagernet/gvisor v0.0.0-20230930141345-5fef6f2e17ab // indirect
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect
github.com/sagernet/sing-mux v0.1.5-0.20231109075101-6b086ed6bb07 // indirect
github.com/sagernet/sing-shadowtls v0.1.4 // indirect
github.com/sagernet/sing-tun v0.1.21-0.20231119035513-f6ea97c5af71 // indirect
github.com/sagernet/sing-tun v0.1.20-0.20231116102736-3fa4ee409a9d // indirect
github.com/sagernet/sing-vmess v0.1.8 // indirect
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 // indirect
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6 // indirect
@@ -92,12 +92,12 @@ require (
go.uber.org/zap v1.26.0 // indirect
go4.org/netipx v0.0.0-20230824141953-6213f710f925 // indirect
golang.org/x/crypto v0.15.0 // indirect
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/mod v0.13.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.4.0 // indirect
golang.org/x/tools v0.15.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.14.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/grpc v1.59.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect

View File

@@ -87,8 +87,8 @@ github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczG
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
@@ -121,8 +121,8 @@ github.com/sagernet/cloudflare-tls v0.0.0-20230829051644-4a68352d0c4a h1:wZHruBx
github.com/sagernet/cloudflare-tls v0.0.0-20230829051644-4a68352d0c4a/go.mod h1:dNV1ZP9y3qx5ltULeKaQZTZWTLHflgW5DES+Ses7cMI=
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA=
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms=
github.com/sagernet/gvisor v0.0.0-20231119034329-07cfb6aaf930 h1:dSPgjIw0CT6ISLeEh8Q20dZMBMFCcEceo23+LncRcNQ=
github.com/sagernet/gvisor v0.0.0-20231119034329-07cfb6aaf930/go.mod h1:JpKHkOYgh4wLwrX2BhH3ZIvCvazCkTnPeEcmigZJfHY=
github.com/sagernet/gvisor v0.0.0-20230930141345-5fef6f2e17ab h1:u+xQoi/Yc6bNUvTfrDD6HhGRybn2lzrhf5vmS+wb4Ho=
github.com/sagernet/gvisor v0.0.0-20230930141345-5fef6f2e17ab/go.mod h1:3akUhSHSVtLuJaYcW5JPepUraBOW06Ibz2HKwaK5rOk=
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-20231008035953-32727fef9460 h1:dAe4OIJAtE0nHOzTHhAReQteh3+sa63rvXbuIpbeOTY=
@@ -131,22 +131,22 @@ github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byL
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.18-0.20231119032432-6a556bfa50cc h1:dmU0chO0QrBpARo8sqyOc+mvPLW+qux4ca16kb2WIc8=
github.com/sagernet/sing v0.2.18-0.20231119032432-6a556bfa50cc/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
github.com/sagernet/sing-dns v0.1.11 h1:PPrMCVVrAeR3f5X23I+cmvacXJ+kzuyAsBiWyUKhGSE=
github.com/sagernet/sing-dns v0.1.11/go.mod h1:zJ/YjnYB61SYE+ubMcMqVdpaSvsyQ2iShQGO3vuLvvE=
github.com/sagernet/sing v0.2.18-0.20231108041402-4fbbd193203c h1:uask61Pxc3nGqsOSjqnBKrwfODWRoEa80lXm04LNk0E=
github.com/sagernet/sing v0.2.18-0.20231108041402-4fbbd193203c/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
github.com/sagernet/sing-dns v0.1.11-0.20231116102430-5a2133f5d358 h1:psJQg/KXVQTupFFR1liaCAucW+NwCDhe1oYfkmz8EJ8=
github.com/sagernet/sing-dns v0.1.11-0.20231116102430-5a2133f5d358/go.mod h1:vtUimtf7Nq9EdvD5WTpfCr69KL1M7bcgOVKiYBiAY/c=
github.com/sagernet/sing-mux v0.1.5-0.20231109075101-6b086ed6bb07 h1:ncKb5tVOsCQgCsv6UpsA0jinbNb5OQ5GMPJlyQP3EHM=
github.com/sagernet/sing-mux v0.1.5-0.20231109075101-6b086ed6bb07/go.mod h1:u/MZf32xPG8jEKe3t+xUV67EBnKtDtCaPhsJQOQGUYU=
github.com/sagernet/sing-quic v0.1.4 h1:F5KRGXMXKQEmP8VrzVollf9HWcRqggcuG9nRCL+5IJ8=
github.com/sagernet/sing-quic v0.1.4/go.mod h1:aXHVP+osF3w5wJzoWZbJSrX3ceJiU9QMd0KPnKV6C/o=
github.com/sagernet/sing-quic v0.1.4-0.20231111111624-370e6abf6769 h1:V84NPJKirL/oDkvUh9Dor2gMZ+TTNHK3jcedqRkgcQA=
github.com/sagernet/sing-quic v0.1.4-0.20231111111624-370e6abf6769/go.mod h1:iggBfFE2ojS2yYQU8Hnrkm029RsHPdYYIKWqeCI64HE=
github.com/sagernet/sing-shadowsocks v0.2.5 h1:qxIttos4xu6ii7MTVJYA8EFQR7Q3KG6xMqmLJIFtBaY=
github.com/sagernet/sing-shadowsocks v0.2.5/go.mod h1:MGWGkcU2xW2G2mfArT9/QqpVLOGU+dBaahZCtPHdt7A=
github.com/sagernet/sing-shadowsocks2 v0.1.5 h1:JDeAJ4ZWlYZ7F6qEVdDKPhQEangxKw/JtmU+i/YfCYE=
github.com/sagernet/sing-shadowsocks2 v0.1.5/go.mod h1:KF65y8lI5PGHyMgRZGYXYsH9ilgRc/yr+NYbSNGuBm4=
github.com/sagernet/sing-shadowsocks2 v0.1.4 h1:vht2M8t3m5DTgXR2j24KbYOygG5aOp+MUhpQnAux728=
github.com/sagernet/sing-shadowsocks2 v0.1.4/go.mod h1:Mgdee99NxxNd5Zld3ixIs18yVs4x2dI2VTDDE1N14Wc=
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.21-0.20231119035513-f6ea97c5af71 h1:WQi0TwhjbSNFFbxybIgAUSjVvo7uWSsLD28ldoM2avY=
github.com/sagernet/sing-tun v0.1.21-0.20231119035513-f6ea97c5af71/go.mod h1:hyzA4gDWbeg2SXklqPDswBKa//QcjlZqKw9aPcNdQ9A=
github.com/sagernet/sing-tun v0.1.20-0.20231116102736-3fa4ee409a9d h1:FlCho4lZEMC6N6dThTVd2rOkWPW0iTqgy7YEAboeyps=
github.com/sagernet/sing-tun v0.1.20-0.20231116102736-3fa4ee409a9d/go.mod h1:B1y93eY/4pNklxrstVGFrDrH4dUZAiZFBQ4MFn6HJXA=
github.com/sagernet/sing-vmess v0.1.8 h1:XVWad1RpTy9b5tPxdm5MCU8cGfrTGdR8qCq6HV2aCNc=
github.com/sagernet/sing-vmess v0.1.8/go.mod h1:vhx32UNzTDUkNwOyIjcZQohre1CaytquC5mPplId8uA=
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as=
@@ -196,12 +196,12 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -213,7 +213,7 @@ golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
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=
@@ -236,14 +236,14 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY=
golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=
golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk=
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@@ -74,23 +74,6 @@ func TestShadowsocks2022(t *testing.T) {
}
}
func TestShadowsocks2022EIH(t *testing.T) {
for _, method16 := range []string{
"2022-blake3-aes-128-gcm",
} {
t.Run(method16, func(t *testing.T) {
testShadowsocks2022EIH(t, method16, mkBase64(t, 16))
})
}
for _, method32 := range []string{
"2022-blake3-aes-256-gcm",
} {
t.Run(method32, func(t *testing.T) {
testShadowsocks2022EIH(t, method32, mkBase64(t, 32))
})
}
}
func testShadowsocksInboundWithShadowsocksRust(t *testing.T, method string, password string) {
startDockerContainer(t, DockerOptions{
Image: ImageShadowsocksRustClient,
@@ -269,67 +252,6 @@ func TestShadowsocksUoT(t *testing.T) {
testSuit(t, clientPort, testPort)
}
func testShadowsocks2022EIH(t *testing.T, method string, password string) {
startInstance(t, option.Options{
Inbounds: []option.Inbound{
{
Type: C.TypeMixed,
Tag: "mixed-in",
MixedOptions: option.HTTPMixedInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: clientPort,
},
},
},
{
Type: C.TypeShadowsocks,
ShadowsocksOptions: option.ShadowsocksInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: serverPort,
},
Method: method,
Password: password,
Users: []option.ShadowsocksUser{
{
Password: password,
},
},
},
},
},
Outbounds: []option.Outbound{
{
Type: C.TypeDirect,
},
{
Type: C.TypeShadowsocks,
Tag: "ss-out",
ShadowsocksOptions: option.ShadowsocksOutboundOptions{
ServerOptions: option.ServerOptions{
Server: "127.0.0.1",
ServerPort: serverPort,
},
Method: method,
Password: password + ":" + password,
},
},
},
Route: &option.RouteOptions{
Rules: []option.Rule{
{
DefaultOptions: option.DefaultRule{
Inbound: []string{"mixed-in"},
Outbound: "ss-out",
},
},
},
},
})
testSuit(t, clientPort, testPort)
}
func mkBase64(t *testing.T, length int) string {
psk := make([]byte, length)
_, err := rand.Read(psk)

View File

@@ -87,15 +87,9 @@ func (t *Transport) Start() error {
}
func (t *Transport) Reset() {
for _, transport := range t.transports {
transport.Reset()
}
}
func (t *Transport) Close() error {
for _, transport := range t.transports {
transport.Close()
}
if t.interfaceCallback != nil {
t.router.InterfaceMonitor().UnregisterCallback(t.interfaceCallback)
}
@@ -272,9 +266,6 @@ func (t *Transport) recreateServers(iface *net.Interface, serverAddrs []netip.Ad
}
transports = append(transports, serverTransport)
}
for _, transport := range t.transports {
transport.Close()
}
t.transports = transports
return nil
}

View File

@@ -49,9 +49,7 @@ func newLateGunConn(writer io.Writer) *GunConn {
}
func (c *GunConn) setup(reader io.Reader, err error) {
if reader != nil {
c.reader = std_bufio.NewReader(reader)
}
c.reader = std_bufio.NewReader(reader)
c.err = err
close(c.create)
}
@@ -145,7 +143,7 @@ func (c *GunConn) LocalAddr() net.Addr {
}
func (c *GunConn) RemoteAddr() net.Addr {
return M.Socksaddr{}
return nil
}
func (c *GunConn) SetDeadline(t time.Time) error {

View File

@@ -53,6 +53,9 @@ func NewServer(ctx context.Context, options option.V2RayHTTPOptions, tlsConfig t
method: options.Method,
headers: options.Headers.Build(),
}
if server.method == "" {
server.method = "PUT"
}
if !strings.HasPrefix(server.path, "/") {
server.path = "/" + server.path
}
@@ -82,7 +85,7 @@ func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
s.invalidRequest(writer, request, http.StatusNotFound, E.New("bad path: ", request.URL.Path))
return
}
if s.method != "" && request.Method != s.method {
if request.Method != s.method {
s.invalidRequest(writer, request, http.StatusNotFound, E.New("bad method: ", request.Method))
return
}

View File

@@ -12,9 +12,6 @@ import (
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio"
"github.com/sagernet/sing/common/bufio/deadline"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
@@ -90,35 +87,18 @@ func (c *Client) dialContext(ctx context.Context, requestURL *url.URL, headers h
return nil, err
}
}
var deadlineConn net.Conn
if deadline.NeedAdditionalReadDeadline(conn) {
deadlineConn = deadline.NewConn(conn)
} else {
deadlineConn = conn
}
err = deadlineConn.SetDeadline(time.Now().Add(C.TCPTimeout))
if err != nil {
return nil, E.Cause(err, "set read deadline")
}
conn.SetDeadline(time.Now().Add(C.TCPTimeout))
var protocols []string
if protocolHeader := headers.Get("Sec-WebSocket-Protocol"); protocolHeader != "" {
protocols = []string{protocolHeader}
headers.Del("Sec-WebSocket-Protocol")
}
reader, _, err := ws.Dialer{Header: ws.HandshakeHeaderHTTP(headers), Protocols: protocols}.Upgrade(deadlineConn, requestURL)
deadlineConn.SetDeadline(time.Time{})
reader, _, err := ws.Dialer{Header: ws.HandshakeHeaderHTTP(headers), Protocols: protocols}.Upgrade(conn, requestURL)
conn.SetDeadline(time.Time{})
if err != nil {
return nil, err
}
if reader != nil {
buffer := buf.NewSize(reader.Buffered())
_, err = buffer.ReadFullFrom(reader, buffer.Len())
if err != nil {
return nil, err
}
conn = bufio.NewCachedConn(conn, buffer)
}
return NewConn(conn, nil, ws.StateClientSide), nil
return NewConn(conn, reader, nil, ws.StateClientSide), nil
}
func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {

View File

@@ -1,6 +1,7 @@
package v2raywebsocket
import (
"bufio"
"context"
"encoding/base64"
"io"
@@ -14,7 +15,6 @@ import (
"github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/debug"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
"github.com/sagernet/ws"
"github.com/sagernet/ws/wsutil"
)
@@ -28,13 +28,19 @@ type WebsocketConn struct {
remoteAddr net.Addr
}
func NewConn(conn net.Conn, remoteAddr net.Addr, state ws.State) *WebsocketConn {
func NewConn(conn net.Conn, br *bufio.Reader, remoteAddr net.Addr, state ws.State) *WebsocketConn {
controlHandler := wsutil.ControlFrameHandler(conn, state)
var reader io.Reader
if br != nil && br.Buffered() > 0 {
reader = br
} else {
reader = conn
}
return &WebsocketConn{
Conn: conn,
state: state,
reader: &wsutil.Reader{
Source: conn,
Source: reader,
State: state,
SkipHeaderCheck: !debug.Enabled,
OnIntermediate: controlHandler,
@@ -233,14 +239,14 @@ func (c *EarlyWebsocketConn) Close() error {
func (c *EarlyWebsocketConn) LocalAddr() net.Addr {
if c.conn == nil {
return M.Socksaddr{}
return nil
}
return c.conn.LocalAddr()
}
func (c *EarlyWebsocketConn) RemoteAddr() net.Addr {
if c.conn == nil {
return M.Socksaddr{}
return nil
}
return c.conn.RemoteAddr()
}

View File

@@ -88,14 +88,14 @@ func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
s.invalidRequest(writer, request, http.StatusBadRequest, E.Cause(err, "decode early data"))
return
}
wsConn, _, _, err := ws.UpgradeHTTP(request, writer)
wsConn, reader, _, err := ws.UpgradeHTTP(request, writer)
if err != nil {
s.invalidRequest(writer, request, 0, E.Cause(err, "upgrade websocket connection"))
return
}
var metadata M.Metadata
metadata.Source = sHttp.SourceAddress(request)
conn = NewConn(wsConn, metadata.Source.TCPAddr(), ws.StateServerSide)
conn = NewConn(wsConn, reader.Reader, metadata.Source.TCPAddr(), ws.StateServerSide)
if len(earlyData) > 0 {
conn = bufio.NewCachedConn(conn, buf.As(earlyData))
}