Compare commits

..

25 Commits

Author SHA1 Message Date
renovate[bot]
05a431d203 [dependencies] Update actions/checkout digest to eef6144 2024-10-07 18:49:40 +00:00
世界
e68a9e623f documentation: Bump version 2024-10-07 04:58:58 +08:00
世界
a9bb07db4a Update utls to v1.6.7 2024-10-07 04:58:58 +08:00
srk24
a07219d16d Add process_path_regex rule type 2024-10-07 04:58:58 +08:00
世界
6362b778c9 clash-api: Add PNA support 2024-10-07 04:58:57 +08:00
世界
cb46b648d7 Add RDP sniffer 2024-10-07 04:58:57 +08:00
世界
04613c27e2 Add SSH sniffer 2024-10-07 04:58:57 +08:00
世界
795e1cf2f0 Write close error to log 2024-10-07 04:58:56 +08:00
世界
1e36c75336 Add AdGuard DNS filter support 2024-10-07 04:58:56 +08:00
世界
5a2c7037fe Improve QUIC sniffer 2024-10-07 04:58:56 +08:00
世界
852c07c050 Add inline rule-set & Add reload for local rule-set 2024-10-07 04:58:56 +08:00
世界
c2ab497ff4 Unique rule-set names 2024-10-07 04:58:54 +08:00
世界
1e3c136440 Add accept empty DNS rule option 2024-10-07 04:58:54 +08:00
世界
7a2cd77798 Add custom options for TUN auto-route and auto-redirect 2024-10-07 04:58:54 +08:00
世界
1cdaea49b6 Improve base DNS transports & Minor fixes 2024-10-07 04:58:53 +08:00
世界
a50b0bc1a9 Add auto-redirect & Improve auto-route 2024-10-07 04:58:53 +08:00
世界
00e6210928 Add rule-set decompile command 2024-10-07 04:58:53 +08:00
世界
2dbeb63b4e Add IP address support for rule-set match match 2024-10-07 04:58:52 +08:00
世界
744cc985ba Improve usages of json.Unmarshal 2024-10-07 04:58:52 +08:00
世界
bd122478fc Bump rule-set version 2024-10-07 04:58:51 +08:00
世界
a18179ad24 Implement read deadline for QUIC based UDP inbounds 2024-10-07 04:58:50 +08:00
世界
388c75a815 WTF is this 2024-10-07 04:58:50 +08:00
世界
8d0d49c388 platform: Fix clash server reload on android 2024-10-07 04:58:50 +08:00
世界
03f5d6e4f2 platform: Add log update interval 2024-10-07 04:58:50 +08:00
世界
25065d766a platform: Prepare connections list 2024-10-07 04:58:49 +08:00
45 changed files with 231 additions and 589 deletions

View File

@@ -91,6 +91,15 @@ func ContextFrom(ctx context.Context) *InboundContext {
return metadata.(*InboundContext) return metadata.(*InboundContext)
} }
func AppendContext(ctx context.Context) (context.Context, *InboundContext) {
metadata := ContextFrom(ctx)
if metadata != nil {
return ctx, metadata
}
metadata = new(InboundContext)
return WithContext(ctx, metadata), metadata
}
func ExtendContext(ctx context.Context) (context.Context, *InboundContext) { func ExtendContext(ctx context.Context) (context.Context, *InboundContext) {
var newMetadata InboundContext var newMetadata InboundContext
if metadata := ContextFrom(ctx); metadata != nil { if metadata := ContextFrom(ctx); metadata != nil {

View File

@@ -2,17 +2,13 @@ package adapter
import ( import (
"context" "context"
"net"
"net/http" "net/http"
"net/netip" "net/netip"
"sync"
"github.com/sagernet/sing-box/common/geoip" "github.com/sagernet/sing-box/common/geoip"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-dns" "github.com/sagernet/sing-dns"
"github.com/sagernet/sing-tun" "github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common/control" "github.com/sagernet/sing/common/control"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/x/list" "github.com/sagernet/sing/common/x/list"
"github.com/sagernet/sing/service" "github.com/sagernet/sing/service"
@@ -102,7 +98,7 @@ type DNSRule interface {
type RuleSet interface { type RuleSet interface {
Name() string Name() string
StartContext(ctx context.Context, startContext *HTTPStartContext) error StartContext(ctx context.Context, startContext RuleSetStartContext) error
PostStart() error PostStart() error
Metadata() RuleSetMetadata Metadata() RuleSetMetadata
ExtractIPSet() []*netipx.IPSet ExtractIPSet() []*netipx.IPSet
@@ -122,42 +118,10 @@ type RuleSetMetadata struct {
ContainsWIFIRule bool ContainsWIFIRule bool
ContainsIPCIDRRule bool ContainsIPCIDRRule bool
} }
type HTTPStartContext struct {
access sync.Mutex
httpClientCache map[string]*http.Client
}
func NewHTTPStartContext() *HTTPStartContext { type RuleSetStartContext interface {
return &HTTPStartContext{ HTTPClient(detour string, dialer N.Dialer) *http.Client
httpClientCache: make(map[string]*http.Client), Close()
}
}
func (c *HTTPStartContext) HTTPClient(detour string, dialer N.Dialer) *http.Client {
c.access.Lock()
defer c.access.Unlock()
if httpClient, loaded := c.httpClientCache[detour]; loaded {
return httpClient
}
httpClient := &http.Client{
Transport: &http.Transport{
ForceAttemptHTTP2: true,
TLSHandshakeTimeout: C.TCPTimeout,
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
},
},
}
c.httpClientCache[detour] = httpClient
return httpClient
}
func (c *HTTPStartContext) Close() {
c.access.Lock()
defer c.access.Unlock()
for _, client := range c.httpClientCache {
client.CloseIdleConnections()
}
} }
type InterfaceUpdateListener interface { type InterfaceUpdateListener interface {

View File

@@ -58,7 +58,7 @@ func FindSDK() {
} }
func findNDK() bool { func findNDK() bool {
const fixedVersion = "27.2.12479018" const fixedVersion = "26.2.11394342"
const versionFile = "source.properties" const versionFile = "source.properties"
if fixedPath := filepath.Join(androidSDKPath, "ndk", fixedVersion); rw.IsFile(filepath.Join(fixedPath, versionFile)) { if fixedPath := filepath.Join(androidSDKPath, "ndk", fixedVersion); rw.IsFile(filepath.Join(fixedPath, versionFile)) {
androidNDKPath = fixedPath androidNDKPath = fixedPath
@@ -86,7 +86,7 @@ func findNDK() bool {
}) })
for _, versionName := range versionNames { for _, versionName := range versionNames {
currentNDKPath := filepath.Join(androidSDKPath, "ndk", versionName) currentNDKPath := filepath.Join(androidSDKPath, "ndk", versionName)
if rw.IsFile(filepath.Join(currentNDKPath, versionFile)) { if rw.IsFile(filepath.Join(androidSDKPath, versionFile)) {
androidNDKPath = currentNDKPath androidNDKPath = currentNDKPath
log.Warn("reproducibility warning: using NDK version " + versionName + " instead of " + fixedVersion) log.Warn("reproducibility warning: using NDK version " + versionName + " instead of " + fixedVersion)
return true return true

View File

@@ -7,10 +7,8 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/sagernet/sing-box/experimental/deprecated"
_ "github.com/sagernet/sing-box/include" _ "github.com/sagernet/sing-box/include"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/service"
"github.com/sagernet/sing/service/filemanager" "github.com/sagernet/sing/service/filemanager"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@@ -67,5 +65,4 @@ func preRun(cmd *cobra.Command, args []string) {
if len(configPaths) == 0 && len(configDirectories) == 0 { if len(configPaths) == 0 && len(configDirectories) == 0 {
configPaths = append(configPaths, "config.json") configPaths = append(configPaths, "config.json")
} }
globalCtx = service.ContextWith(globalCtx, deprecated.NewEnvManager(log.StdLogger()))
} }

View File

@@ -2,118 +2,10 @@
icon: material/alert-decagram icon: material/alert-decagram
--- ---
#### 1.11.0-alpha.2 #### 1.10.0-beta.12
* Add warnings for usage of deprecated features
* Fixes and improvements
#### 1.11.0-alpha.1
* Update quic-go to v0.48.0
* Fixes and improvements
### 1.10.1
* Fixes and improvements * Fixes and improvements
### 1.10.0
Important changes since 1.9:
* Introducing auto-redirect **1**
* Add AdGuard DNS Filter support **2**
* TUN address fields are merged **3**
* Add custom options for `auto-route` and `auto-redirect` **4**
* Drop support for go1.18 and go1.19 **5**
* Add tailing comma support in JSON configuration
* Improve sniffers **6**
* Add new `inline` rule-set type **7**
* Add access control options for Clash API **8**
* Add `rule_set_ip_cidr_accept_empty` DNS address filter rule item **9**
* Add auto reload support for local rule-set
* Update fsnotify usages **10**
* Add IP address support for `rule-set match` command
* Add `rule-set decompile` command
* Add `process_path_regex` rule item
* Update uTLS to v1.6.7 **11**
* Optimize memory usages of rule-sets **12**
**1**:
The new auto-redirect feature allows TUN to automatically
configure connection redirection to improve proxy performance.
When auto-redirect is enabled, new route address set options will allow you to
automatically configure destination IP CIDR rules from a specified rule set to the firewall.
Specified or unspecified destinations will bypass the sing-box routes to get better performance
(for example, keep hardware offloading of direct traffics on the router).
See [TUN](/configuration/inbound/tun).
**2**:
The new feature allows you to use AdGuard DNS Filter lists in a sing-box without AdGuard Home.
See [AdGuard DNS Filter](/configuration/rule-set/adguard/).
**3**:
See [Migration](/migration/#tun-address-fields-are-merged).
**4**:
See [iproute2_table_index](/configuration/inbound/tun/#iproute2_table_index),
[iproute2_rule_index](/configuration/inbound/tun/#iproute2_rule_index),
[auto_redirect_input_mark](/configuration/inbound/tun/#auto_redirect_input_mark) and
[auto_redirect_output_mark](/configuration/inbound/tun/#auto_redirect_output_mark).
**5**:
Due to maintenance difficulties, sing-box 1.10.0 requires at least Go 1.20 to compile.
**6**:
BitTorrent, DTLS, RDP, SSH sniffers are added.
Now the QUIC sniffer can correctly extract the server name from Chromium requests and
can identify common QUIC clients, including
Chromium, Safari, Firefox, quic-go (including uquic disguised as Chrome).
**7**:
The new [rule-set](/configuration/rule-set/) type inline (which also becomes the default type)
allows you to write headless rules directly without creating a rule-set file.
**8**:
With the new access control options, not only can you allow Clash dashboards
to access the Clash API on your local network,
you can also manually limit the websites that can access the API instead of allowing everyone.
See [Clash API](/configuration/experimental/clash-api/).
**9**:
See [DNS Rule](/configuration/dns/rule/#rule_set_ip_cidr_accept_empty).
**10**:
sing-box now uses fsnotify correctly and will not cancel watching
if the target file is deleted or recreated via rename (e.g. `mv`).
This affects all path options that support reload, including
`tls.certificate_path`, `tls.key_path`, `tls.ech.key_path` and `rule_set.path`.
**11**:
Some legacy chrome fingerprints have been removed and will fallback to chrome,
see [utls](/configuration/shared/tls#utls).
**12**:
See [Source Format](/configuration/rule-set/source-format/#version).
### 1.9.7 ### 1.9.7
* Fixes and improvements * Fixes and improvements
@@ -121,20 +13,18 @@ See [Source Format](/configuration/rule-set/source-format/#version).
#### 1.10.0-beta.11 #### 1.10.0-beta.11
* Update uTLS to v1.6.7 **1** * Update uTLS to v1.6.7 **1**
* Add ipk in release artifacts
**1**: **1**:
Some legacy chrome fingerprints have been removed and will fallback to chrome, Some legacy chrome fingerprints have been removed and will fallback to chrome, see [utls](/configuration/shared/tls#utls).
see [utls](/configuration/shared/tls#utls).
#### 1.10.0-beta.10 #### 1.10.0-beta.10
* Add `process_path_regex` rule item * Add `process_path_regex` rule item
* Fixes and improvements * Fixes and improvements
_The macOS standalone versions of sing-box (>=1.9.5/<1.10.0-beta.11) now silently fail and require manual granting of _The macOS standalone versions of sing-box (>=1.9.5/<1.10.0-beta.11) now silently fail and require manual granting of the **Full Disk Access** permission to system extension to start, probably due to Apple's changed security policy. We will prompt users about this in feature versions._
the **Full Disk Access** permission to system extension to start, probably due to Apple's changed security policy. We
will prompt users about this in feature versions._
### 1.9.6 ### 1.9.6
@@ -164,8 +54,7 @@ We are still working on getting all sing-box apps back on the App Store, which s
* Fixes and improvements * Fixes and improvements
_With the help of a netizen, we are in the process of getting sing-box apps back on the App Store, which should be _With the help of a netizen, we are in the process of getting sing-box apps back on the App Store, which should be completed within a month (TestFlight is already available)._
completed within a month (TestFlight is already available)._
#### 1.10.0-beta.7 #### 1.10.0-beta.7
@@ -270,9 +159,11 @@ See [Source Format](/configuration/rule-set/source-format/#version).
**1**: **1**:
The new [rule-set](/configuration/rule-set/) type inline (which also becomes the default type) The new [rule-set] type inline (which also becomes the default type)
allows you to write headless rules directly without creating a rule-set file. allows you to write headless rules directly without creating a rule-set file.
[rule-set]: /configuration/rule-set/
**2**: **2**:
sing-box now uses fsnotify correctly and will not cancel watching sing-box now uses fsnotify correctly and will not cancel watching

View File

@@ -232,12 +232,12 @@ Automatically configure iptables/nftables to redirect connections.
*In Android* *In Android*
Only local IPv4 connections are forwarded. To share your VPN connection over hotspot or repeater, Only local connections are forwarded. To share your VPN connection over hotspot or repeater,
use [VPNHotspot](https://github.com/Mygod/VPNHotspot). use [VPNHotspot](https://github.com/Mygod/VPNHotspot).
*In Linux*: *In Linux*:
`auto_route` with `auto_redirect` works as expected on routers **without intervention**. `auto_route` with `auto_redirect` now works as expected on routers **without intervention**.
#### auto_redirect_input_mark #### auto_redirect_input_mark

View File

@@ -232,7 +232,7 @@ tun 接口的 IPv6 前缀。
仅支持 Linux且需要 `auto_route` 已启用。 仅支持 Linux且需要 `auto_route` 已启用。
自动配置 iptables/nftables 以重定向连接。 自动配置 iptables 以重定向 TCP 连接。
*在 Android 中* *在 Android 中*
@@ -240,7 +240,7 @@ tun 接口的 IPv6 前缀。
*在 Linux 中*: *在 Linux 中*:
带有 `auto_redirect ``auto_route` 可以在路由器上按预期工作,**无需干预**。 带有 `auto_redirect ``auto_route` 现在可以在路由器上按预期工作,**无需干预**。
#### auto_redirect_input_mark #### auto_redirect_input_mark

View File

@@ -14,11 +14,6 @@ icon: material/delete-alert
Old fields are deprecated and will be removed in sing-box 1.11.0. Old fields are deprecated and will be removed in sing-box 1.11.0.
#### Match source rule items are renamed
`rule_set_ipcidr_match_source` route and DNS rule items are renamed to
`rule_set_ip_cidr_match_source` and will be remove in sing-box 1.11.0.
#### Drop support for go1.18 and go1.19 #### Drop support for go1.18 and go1.19
Due to maintenance difficulties, sing-box 1.10.0 requires at least Go 1.20 to compile. Due to maintenance difficulties, sing-box 1.10.0 requires at least Go 1.20 to compile.

View File

@@ -6,18 +6,13 @@ icon: material/delete-alert
## 1.10.0 ## 1.10.0
#### Match source 规则项已重命名
`rule_set_ipcidr_match_source` 路由和 DNS 规则项已被重命名为
`rule_set_ip_cidr_match_source` 且将在 sing-box 1.11.0 中被移除。
#### TUN 地址字段已合并 #### TUN 地址字段已合并
`inet4_address``inet6_address` 已合并为 `address` `inet4_address``inet6_address` 已合并为 `address`
`inet4_route_address``inet6_route_address` 已合并为 `route_address` `inet4_route_address``inet6_route_address` 已合并为 `route_address`
`inet4_route_exclude_address``inet6_route_exclude_address` 已合并为 `route_exclude_address` `inet4_route_exclude_address``inet6_route_exclude_address` 已合并为 `route_exclude_address`
旧字段已废弃,且将在 sing-box 1.11.0 中移除。 旧字段已废弃,且将在 sing-box 1.11.0 中移除。
#### 移除对 go1.18 和 go1.19 的支持 #### 移除对 go1.18 和 go1.19 的支持

View File

@@ -1,86 +0,0 @@
package deprecated
import (
C "github.com/sagernet/sing-box/constant"
F "github.com/sagernet/sing/common/format"
"golang.org/x/mod/semver"
)
type Note struct {
Name string
Description string
DeprecatedVersion string
ScheduledVersion string
EnvName string
MigrationLink string
}
func (n Note) Impending() bool {
if n.ScheduledVersion == "" {
return false
}
if !semver.IsValid("v" + C.Version) {
return false
}
versionMinor := semver.Compare(semver.MajorMinor("v"+C.Version), "v"+n.ScheduledVersion)
if versionMinor < 0 {
panic("invalid deprecated note: " + n.Name)
}
return versionMinor <= 1
}
func (n Note) Message() string {
return F.ToString(
n.Description, " is deprecated in sing-box ", n.DeprecatedVersion,
" and will be removed in sing-box ", n.ScheduledVersion, ", please checkout documentation for migration.",
)
}
func (n Note) MessageWithLink() string {
return F.ToString(
n.Description, " is deprecated in sing-box ", n.DeprecatedVersion,
" and will be removed in sing-box ", n.ScheduledVersion, ", checkout documentation for migration: ", n.MigrationLink,
)
}
var OptionBadMatchSource = Note{
Name: "bad-match-source",
Description: "legacy match source rule item",
DeprecatedVersion: "1.10.0",
ScheduledVersion: "1.11.0",
MigrationLink: "https://sing-box.sagernet.org/deprecated/#match-source-rule-items-are-renamed",
}
var OptionGEOIP = Note{
Name: "geoip",
Description: "geoip database",
DeprecatedVersion: "1.8.0",
ScheduledVersion: "1.12.0",
EnvName: "GEOIP",
MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-geoip-to-rule-sets",
}
var OptionGEOSITE = Note{
Name: "geosite",
Description: "geosite database",
DeprecatedVersion: "1.8.0",
ScheduledVersion: "1.12.0",
EnvName: "GEOSITE",
MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-geosite-to-rule-sets",
}
var OptionTUNAddressX = Note{
Name: "tun-address-x",
Description: "legacy tun address fields",
DeprecatedVersion: "1.10.0",
ScheduledVersion: "1.12.0",
MigrationLink: "https://sing-box.sagernet.org/migration/#tun-address-fields-are-merged",
}
var Options = []Note{
OptionBadMatchSource,
OptionGEOIP,
OptionGEOSITE,
OptionTUNAddressX,
}

View File

@@ -1,30 +0,0 @@
package deprecated
import (
"os"
"strconv"
"github.com/sagernet/sing/common/logger"
)
type envManager struct {
logger logger.Logger
}
func NewEnvManager(logger logger.Logger) Manager {
return &envManager{logger: logger}
}
func (f *envManager) ReportDeprecated(feature Note) {
if !feature.Impending() {
f.logger.Warn(feature.MessageWithLink())
return
}
enable, enableErr := strconv.ParseBool(os.Getenv("ENABLE_DEPRECATED_" + feature.EnvName))
if enableErr == nil && enable {
f.logger.Warn(feature.MessageWithLink())
return
}
f.logger.Error(feature.MessageWithLink())
f.logger.Fatal("to continuing using this feature, set ENABLE_DEPRECATED_" + feature.EnvName + "=true")
}

View File

@@ -1,19 +0,0 @@
package deprecated
import (
"context"
"github.com/sagernet/sing/service"
)
type Manager interface {
ReportDeprecated(feature Note)
}
func Report(ctx context.Context, feature Note) {
manager := service.FromContext[Manager](ctx)
if manager == nil {
return
}
manager.ReportDeprecated(feature)
}

View File

@@ -16,5 +16,4 @@ const (
CommandSetSystemProxyEnabled CommandSetSystemProxyEnabled
CommandConnections CommandConnections
CommandCloseConnection CommandCloseConnection
CommandGetDeprecatedNotes
) )

View File

@@ -18,10 +18,6 @@ func (c *CommandClient) CloseConnection(connId string) error {
return err return err
} }
defer conn.Close() defer conn.Close()
err = binary.Write(conn, binary.BigEndian, uint8(CommandCloseConnection))
if err != nil {
return err
}
writer := bufio.NewWriter(conn) writer := bufio.NewWriter(conn)
err = varbin.Write(writer, binary.BigEndian, connId) err = varbin.Write(writer, binary.BigEndian, connId)
if err != nil { if err != nil {

View File

@@ -25,7 +25,6 @@ func (c *CommandClient) handleConnectionsConn(conn net.Conn) {
connections Connections connections Connections
) )
for { for {
rawConnections = nil
err := varbin.Read(reader, binary.BigEndian, &rawConnections) err := varbin.Read(reader, binary.BigEndian, &rawConnections)
if err != nil { if err != nil {
c.handler.Disconnected(err.Error()) c.handler.Disconnected(err.Error())

View File

@@ -1,46 +0,0 @@
package libbox
import (
"encoding/binary"
"net"
"github.com/sagernet/sing-box/experimental/deprecated"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/varbin"
"github.com/sagernet/sing/service"
)
func (c *CommandClient) GetDeprecatedNotes() (DeprecatedNoteIterator, error) {
conn, err := c.directConnect()
if err != nil {
return nil, err
}
defer conn.Close()
err = binary.Write(conn, binary.BigEndian, uint8(CommandGetDeprecatedNotes))
if err != nil {
return nil, err
}
err = readError(conn)
if err != nil {
return nil, err
}
var features []deprecated.Note
err = varbin.Read(conn, binary.BigEndian, &features)
if err != nil {
return nil, err
}
return newIterator(common.Map(features, func(it deprecated.Note) *DeprecatedNote { return (*DeprecatedNote)(&it) })), nil
}
func (s *CommandServer) handleGetDeprecatedNotes(conn net.Conn) error {
boxService := s.service
if boxService == nil {
return writeError(conn, E.New("service not ready"))
}
err := writeError(conn, nil)
if err != nil {
return err
}
return varbin.Write(conn, binary.BigEndian, service.FromContext[deprecated.Manager](boxService.ctx).(*deprecatedManager).Get())
}

View File

@@ -174,8 +174,6 @@ func (s *CommandServer) handleConnection(conn net.Conn) error {
return s.handleConnectionsConn(conn) return s.handleConnectionsConn(conn)
case CommandCloseConnection: case CommandCloseConnection:
return s.handleCloseConnection(conn) return s.handleCloseConnection(conn)
case CommandGetDeprecatedNotes:
return s.handleGetDeprecatedNotes(conn)
default: default:
return E.New("unknown command: ", command) return E.New("unknown command: ", command)
} }

View File

@@ -1,56 +0,0 @@
package libbox
import (
"sync"
"github.com/sagernet/sing-box/experimental/deprecated"
)
var _ deprecated.Manager = (*deprecatedManager)(nil)
type deprecatedManager struct {
access sync.Mutex
features []deprecated.Note
}
func (m *deprecatedManager) ReportDeprecated(feature deprecated.Note) {
m.access.Lock()
defer m.access.Unlock()
m.features = append(m.features, feature)
}
func (m *deprecatedManager) Get() []deprecated.Note {
m.access.Lock()
defer m.access.Unlock()
features := m.features
m.features = nil
return features
}
var _ = deprecated.Note(DeprecatedNote{})
type DeprecatedNote struct {
Name string
Description string
DeprecatedVersion string
ScheduledVersion string
EnvName string
MigrationLink string
}
func (n DeprecatedNote) Impending() bool {
return deprecated.Note(n).Impending()
}
func (n DeprecatedNote) Message() string {
return deprecated.Note(n).Message()
}
func (n DeprecatedNote) MessageWithLink() string {
return deprecated.Note(n).MessageWithLink()
}
type DeprecatedNoteIterator interface {
HasNext() bool
Next() *DeprecatedNote
}

View File

@@ -218,7 +218,7 @@ func DecodeProfileContent(data []byte) (*ProfileContent, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = binary.Read(bReader, binary.BigEndian, &content.Type) err = binary.Read(reader, binary.BigEndian, &content.Type)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -233,17 +233,17 @@ func DecodeProfileContent(data []byte) (*ProfileContent, error) {
} }
} }
if content.Type == ProfileTypeRemote || (version == 0 && content.Type != ProfileTypeLocal) { if content.Type == ProfileTypeRemote || (version == 0 && content.Type != ProfileTypeLocal) {
err = binary.Read(bReader, binary.BigEndian, &content.AutoUpdate) err = binary.Read(reader, binary.BigEndian, &content.AutoUpdate)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if version >= 1 { if version >= 1 {
err = binary.Read(bReader, binary.BigEndian, &content.AutoUpdateInterval) err = binary.Read(reader, binary.BigEndian, &content.AutoUpdateInterval)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
err = binary.Read(bReader, binary.BigEndian, &content.LastUpdated) err = binary.Read(reader, binary.BigEndian, &content.LastUpdated)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -14,7 +14,6 @@ import (
"github.com/sagernet/sing-box/common/process" "github.com/sagernet/sing-box/common/process"
"github.com/sagernet/sing-box/common/urltest" "github.com/sagernet/sing-box/common/urltest"
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/experimental/deprecated"
"github.com/sagernet/sing-box/experimental/libbox/internal/procfs" "github.com/sagernet/sing-box/experimental/libbox/internal/procfs"
"github.com/sagernet/sing-box/experimental/libbox/platform" "github.com/sagernet/sing-box/experimental/libbox/platform"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
@@ -50,7 +49,6 @@ func NewService(configContent string, platformInterface PlatformInterface) (*Box
ctx = filemanager.WithDefault(ctx, sWorkingPath, sTempPath, sUserID, sGroupID) ctx = filemanager.WithDefault(ctx, sWorkingPath, sTempPath, sUserID, sGroupID)
urlTestHistoryStorage := urltest.NewHistoryStorage() urlTestHistoryStorage := urltest.NewHistoryStorage()
ctx = service.ContextWithPtr(ctx, urlTestHistoryStorage) ctx = service.ContextWithPtr(ctx, urlTestHistoryStorage)
ctx = service.ContextWith[deprecated.Manager](ctx, new(deprecatedManager))
platformWrapper := &platformInterfaceWrapper{iif: platformInterface, useProcFS: platformInterface.UseProcFS()} platformWrapper := &platformInterfaceWrapper{iif: platformInterface, useProcFS: platformInterface.UseProcFS()}
instance, err := box.New(box.Options{ instance, err := box.New(box.Options{
Context: ctx, Context: ctx,

32
go.mod
View File

@@ -7,16 +7,16 @@ require (
github.com/caddyserver/certmagic v0.20.0 github.com/caddyserver/certmagic v0.20.0
github.com/cloudflare/circl v1.3.7 github.com/cloudflare/circl v1.3.7
github.com/cretz/bine v0.2.0 github.com/cretz/bine v0.2.0
github.com/go-chi/chi/v5 v5.1.0 github.com/go-chi/chi/v5 v5.0.12
github.com/go-chi/render v1.0.3 github.com/go-chi/render v1.0.3
github.com/gofrs/uuid/v5 v5.3.0 github.com/gofrs/uuid/v5 v5.2.0
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2
github.com/libdns/alidns v1.0.3 github.com/libdns/alidns v1.0.3
github.com/libdns/cloudflare v0.1.1 github.com/libdns/cloudflare v0.1.1
github.com/logrusorgru/aurora v2.0.3+incompatible github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/metacubex/tfo-go v0.0.0-20241006021335-daedaf0ca7aa github.com/metacubex/tfo-go v0.0.0-20240821025650-e9be0afd5e7d
github.com/mholt/acmez v1.2.0 github.com/mholt/acmez v1.2.0
github.com/miekg/dns v1.1.62 github.com/miekg/dns v1.1.61
github.com/ooni/go-libtor v1.1.8 github.com/ooni/go-libtor v1.1.8
github.com/oschwald/maxminddb-golang v1.12.0 github.com/oschwald/maxminddb-golang v1.12.0
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
@@ -25,30 +25,29 @@ require (
github.com/sagernet/fswatch v0.1.1 github.com/sagernet/fswatch v0.1.1
github.com/sagernet/gomobile v0.1.4 github.com/sagernet/gomobile v0.1.4
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f
github.com/sagernet/quic-go v0.48.0-beta.1 github.com/sagernet/quic-go v0.47.0-beta.2
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
github.com/sagernet/sing v0.5.0-rc.2 github.com/sagernet/sing v0.5.0-beta.2
github.com/sagernet/sing-dns v0.3.0-rc.2 github.com/sagernet/sing-dns v0.3.0-beta.14
github.com/sagernet/sing-mux v0.2.0 github.com/sagernet/sing-mux v0.2.0
github.com/sagernet/sing-quic v0.3.0-rc.1 github.com/sagernet/sing-quic v0.3.0-beta.3
github.com/sagernet/sing-shadowsocks v0.2.7 github.com/sagernet/sing-shadowsocks v0.2.7
github.com/sagernet/sing-shadowsocks2 v0.2.0 github.com/sagernet/sing-shadowsocks2 v0.2.0
github.com/sagernet/sing-shadowtls v0.1.4 github.com/sagernet/sing-shadowtls v0.1.4
github.com/sagernet/sing-tun v0.4.0-rc.4 github.com/sagernet/sing-tun v0.4.0-beta.16
github.com/sagernet/sing-vmess v0.1.12 github.com/sagernet/sing-vmess v0.1.12
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7
github.com/sagernet/utls v1.6.7 github.com/sagernet/utls v1.6.7
github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8 github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854
github.com/spf13/cobra v1.8.1 github.com/spf13/cobra v1.8.0
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
go.uber.org/zap v1.27.0 go.uber.org/zap v1.27.0
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
golang.org/x/crypto v0.28.0 golang.org/x/crypto v0.25.0
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
golang.org/x/mod v0.20.0 golang.org/x/net v0.27.0
golang.org/x/net v0.30.0 golang.org/x/sys v0.25.0
golang.org/x/sys v0.26.0
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
google.golang.org/grpc v1.63.2 google.golang.org/grpc v1.63.2
google.golang.org/protobuf v1.33.0 google.golang.org/protobuf v1.33.0
@@ -90,10 +89,11 @@ require (
github.com/vishvananda/netns v0.0.4 // indirect github.com/vishvananda/netns v0.0.4 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect github.com/zeebo/blake3 v0.2.3 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/mod v0.19.0 // indirect
golang.org/x/sync v0.8.0 // indirect golang.org/x/sync v0.8.0 // indirect
golang.org/x/text v0.19.0 // indirect golang.org/x/text v0.18.0 // indirect
golang.org/x/time v0.5.0 // indirect golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.24.0 // indirect golang.org/x/tools v0.23.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect

68
go.sum
View File

@@ -8,7 +8,7 @@ github.com/caddyserver/certmagic v0.20.0 h1:bTw7LcEZAh9ucYCRXyCpIrSAGplplI0vGYJ4
github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg= github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg=
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cretz/bine v0.1.0/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw= github.com/cretz/bine v0.1.0/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw=
github.com/cretz/bine v0.2.0 h1:8GiDRGlTgz+o8H9DSnsl+5MeBK4HsExxgl6WgzOCuZo= github.com/cretz/bine v0.2.0 h1:8GiDRGlTgz+o8H9DSnsl+5MeBK4HsExxgl6WgzOCuZo=
github.com/cretz/bine v0.2.0/go.mod h1:WU4o9QR9wWp8AVKtTM1XD5vUHkEqnf2vVSo6dBqbetI= github.com/cretz/bine v0.2.0/go.mod h1:WU4o9QR9wWp8AVKtTM1XD5vUHkEqnf2vVSo6dBqbetI=
@@ -17,8 +17,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4= github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0= github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
@@ -30,8 +30,8 @@ github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gofrs/uuid/v5 v5.3.0 h1:m0mUMr+oVYUdxpMLgSYCZiXe7PuVPnI94+OMeVBNedk= github.com/gofrs/uuid/v5 v5.2.0 h1:qw1GMx6/y8vhVsx626ImfKMuS5CvJmhIKKtuyvfajMM=
github.com/gofrs/uuid/v5 v5.3.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= github.com/gofrs/uuid/v5 v5.2.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
@@ -70,12 +70,12 @@ github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/
github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw= github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U= github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
github.com/metacubex/tfo-go v0.0.0-20241006021335-daedaf0ca7aa h1:9mcjV+RGZVC3reJBNDjjNPyS8PmFG97zq56X7WNaFO4= github.com/metacubex/tfo-go v0.0.0-20240821025650-e9be0afd5e7d h1:j9LtzkYstLFoNvXW824QQeN7Y26uPL5249kzWKbzO9U=
github.com/metacubex/tfo-go v0.0.0-20241006021335-daedaf0ca7aa/go.mod h1:4tLB5c8U0CxpkFM+AJJB77jEaVDbLH5XQvy42vAGsWw= github.com/metacubex/tfo-go v0.0.0-20240821025650-e9be0afd5e7d/go.mod h1:c7bVFM9f5+VzeZ/6Kg77T/jrg1Xp8QpqlSHvG/aXVts=
github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30= github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE= github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs=
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= 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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss=
@@ -110,27 +110,27 @@ github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZN
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM= github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I= github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I=
github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8= github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8=
github.com/sagernet/quic-go v0.48.0-beta.1 h1:86hQZrmuoARI3BpDRkQaP0iAVpywA4YsRrzJPYuPKWg= github.com/sagernet/quic-go v0.47.0-beta.2 h1:1tCGWFOSaXIeuQaHrwOMJIYvlupjTcaVInGQw5ArULU=
github.com/sagernet/quic-go v0.48.0-beta.1/go.mod h1:1WgdDIVD1Gybp40JTWketeSfKA/+or9YMLaG5VeTk4k= github.com/sagernet/quic-go v0.47.0-beta.2/go.mod h1:bLVKvElSEMNv7pu7SZHscW02TYigzQ5lQu3Nh4wNh8Q=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo= github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
github.com/sagernet/sing v0.5.0-rc.2 h1:tIrs6pRbjJWvI0ITRSg47P1wosY+iSuHpw9t5/hBx+Q= github.com/sagernet/sing v0.5.0-beta.2 h1:V12EpwtsgYo5OLGjAiGoJobDJZeUsKv0b5y+yGAM6W0=
github.com/sagernet/sing v0.5.0-rc.2/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= github.com/sagernet/sing v0.5.0-beta.2/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/sagernet/sing-dns v0.3.0-rc.2 h1:z1yROBxd/6wik5h53Sz5df1DSmbPTaOu/Z0wAmyXGoQ= github.com/sagernet/sing-dns v0.3.0-beta.14 h1:/s+fJzYKsvLaNDt/2rjpsrDcN8wmCO2JbX6OFrl8Nww=
github.com/sagernet/sing-dns v0.3.0-rc.2/go.mod h1:TqLIelI+FAbVEdiTRolhGLOwvhVjY7oT+wezlOJUQ7M= github.com/sagernet/sing-dns v0.3.0-beta.14/go.mod h1:rscgSr5ixOPk8XM9ZMLuMXCyldEQ1nLvdl0nfv+lp00=
github.com/sagernet/sing-mux v0.2.0 h1:4C+vd8HztJCWNYfufvgL49xaOoOHXty2+EAjnzN3IYo= github.com/sagernet/sing-mux v0.2.0 h1:4C+vd8HztJCWNYfufvgL49xaOoOHXty2+EAjnzN3IYo=
github.com/sagernet/sing-mux v0.2.0/go.mod h1:khzr9AOPocLa+g53dBplwNDz4gdsyx/YM3swtAhlkHQ= github.com/sagernet/sing-mux v0.2.0/go.mod h1:khzr9AOPocLa+g53dBplwNDz4gdsyx/YM3swtAhlkHQ=
github.com/sagernet/sing-quic v0.3.0-rc.1 h1:SlzL1yfEAKJyRduub8vzOVtbyTLAX7RZEEBZxO5utts= github.com/sagernet/sing-quic v0.3.0-beta.3 h1:8S98VXZxtSiOqVCFbCNbMEvKDPhOF/VNBYMjVC3xMhw=
github.com/sagernet/sing-quic v0.3.0-rc.1/go.mod h1:uX+aUHA0fgIN6U3WViseDpSdTQriViZ7qz0Wbsf1mNQ= github.com/sagernet/sing-quic v0.3.0-beta.3/go.mod h1:rFPUlYnSj1Bx9gFSghjCqrCzfGvpjhkisOiTKpjq5vQ=
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8= github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE= github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wKFHi+8XwgADg= github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wKFHi+8XwgADg=
github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ= github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k= 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-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4=
github.com/sagernet/sing-tun v0.4.0-rc.4 h1:EFz+UjLZTm+YS3ob1vpqjOga67wyvnxWcbQKfe5wE3Y= github.com/sagernet/sing-tun v0.4.0-beta.16 h1:05VdL5BZiKLQsDNrpdXMseSO1NwPfl9Y4o76PqAd9sY=
github.com/sagernet/sing-tun v0.4.0-rc.4/go.mod h1:+lQdWhqD4atzrCgRhoyrxBCg1OBru/hAv2BT3kdgmGM= github.com/sagernet/sing-tun v0.4.0-beta.16/go.mod h1:81JwnnYw8X9W9XvmZetSTTiPgIE3SbAbnc+EHKwPJ5U=
github.com/sagernet/sing-vmess v0.1.12 h1:2gFD8JJb+eTFMoa8FIVMnknEi+vCSfaiTXTfEYAYAPg= github.com/sagernet/sing-vmess v0.1.12 h1:2gFD8JJb+eTFMoa8FIVMnknEi+vCSfaiTXTfEYAYAPg=
github.com/sagernet/sing-vmess v0.1.12/go.mod h1:luTSsfyBGAc9VhtCqwjR+dt1QgqBhuYBCONB/POhF8I= github.com/sagernet/sing-vmess v0.1.12/go.mod h1:luTSsfyBGAc9VhtCqwjR+dt1QgqBhuYBCONB/POhF8I=
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ= github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ=
@@ -141,8 +141,8 @@ github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8 h1:R0OMYASco
github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8/go.mod h1:K4J7/npM+VAMUeUmTa2JaA02JmyheP0GpRBOUvn3ecc= github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8/go.mod h1:K4J7/npM+VAMUeUmTa2JaA02JmyheP0GpRBOUvn3ecc=
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc= 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-20231204124109-acfe8907c854/go.mod h1:LtfoSK3+NG57tvnVEHgcuBW9ujgE8enPSgzgwStwCAA=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -170,16 +170,16 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/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-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.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.19.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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -190,19 +190,19 @@ 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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.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.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 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.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE= 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= golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=

View File

@@ -13,7 +13,6 @@ import (
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/taskmonitor" "github.com/sagernet/sing-box/common/taskmonitor"
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/experimental/deprecated"
"github.com/sagernet/sing-box/experimental/libbox/platform" "github.com/sagernet/sing-box/experimental/libbox/platform"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
@@ -55,18 +54,15 @@ type Tun struct {
func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TunInboundOptions, platformInterface platform.Interface) (*Tun, error) { func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TunInboundOptions, platformInterface platform.Interface) (*Tun, error) {
address := options.Address address := options.Address
var deprecatedAddressUsed bool
//nolint:staticcheck //nolint:staticcheck
//goland:noinspection GoDeprecation //goland:noinspection GoDeprecation
if len(options.Inet4Address) > 0 { if len(options.Inet4Address) > 0 {
address = append(address, options.Inet4Address...) address = append(address, options.Inet4Address...)
deprecatedAddressUsed = true
} }
//nolint:staticcheck //nolint:staticcheck
//goland:noinspection GoDeprecation //goland:noinspection GoDeprecation
if len(options.Inet6Address) > 0 { if len(options.Inet6Address) > 0 {
address = append(address, options.Inet6Address...) address = append(address, options.Inet6Address...)
deprecatedAddressUsed = true
} }
inet4Address := common.Filter(address, func(it netip.Prefix) bool { inet4Address := common.Filter(address, func(it netip.Prefix) bool {
return it.Addr().Is4() return it.Addr().Is4()
@@ -80,13 +76,11 @@ func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger
//goland:noinspection GoDeprecation //goland:noinspection GoDeprecation
if len(options.Inet4RouteAddress) > 0 { if len(options.Inet4RouteAddress) > 0 {
routeAddress = append(routeAddress, options.Inet4RouteAddress...) routeAddress = append(routeAddress, options.Inet4RouteAddress...)
deprecatedAddressUsed = true
} }
//nolint:staticcheck //nolint:staticcheck
//goland:noinspection GoDeprecation //goland:noinspection GoDeprecation
if len(options.Inet6RouteAddress) > 0 { if len(options.Inet6RouteAddress) > 0 {
routeAddress = append(routeAddress, options.Inet6RouteAddress...) routeAddress = append(routeAddress, options.Inet6RouteAddress...)
deprecatedAddressUsed = true
} }
inet4RouteAddress := common.Filter(routeAddress, func(it netip.Prefix) bool { inet4RouteAddress := common.Filter(routeAddress, func(it netip.Prefix) bool {
return it.Addr().Is4() return it.Addr().Is4()
@@ -100,13 +94,11 @@ func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger
//goland:noinspection GoDeprecation //goland:noinspection GoDeprecation
if len(options.Inet4RouteExcludeAddress) > 0 { if len(options.Inet4RouteExcludeAddress) > 0 {
routeExcludeAddress = append(routeExcludeAddress, options.Inet4RouteExcludeAddress...) routeExcludeAddress = append(routeExcludeAddress, options.Inet4RouteExcludeAddress...)
deprecatedAddressUsed = true
} }
//nolint:staticcheck //nolint:staticcheck
//goland:noinspection GoDeprecation //goland:noinspection GoDeprecation
if len(options.Inet6RouteExcludeAddress) > 0 { if len(options.Inet6RouteExcludeAddress) > 0 {
routeExcludeAddress = append(routeExcludeAddress, options.Inet6RouteExcludeAddress...) routeExcludeAddress = append(routeExcludeAddress, options.Inet6RouteExcludeAddress...)
deprecatedAddressUsed = true
} }
inet4RouteExcludeAddress := common.Filter(routeExcludeAddress, func(it netip.Prefix) bool { inet4RouteExcludeAddress := common.Filter(routeExcludeAddress, func(it netip.Prefix) bool {
return it.Addr().Is4() return it.Addr().Is4()
@@ -115,10 +107,6 @@ func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger
return it.Addr().Is6() return it.Addr().Is6()
}) })
if deprecatedAddressUsed {
deprecated.Report(ctx, deprecated.OptionTUNAddressX)
}
tunMTU := options.MTU tunMTU := options.MTU
if tunMTU == 0 { if tunMTU == 0 {
tunMTU = 9000 tunMTU = 9000

View File

@@ -11,22 +11,18 @@ theme:
logo: assets/icon.svg logo: assets/icon.svg
favicon: assets/icon.svg favicon: assets/icon.svg
palette: palette:
- media: "(prefers-color-scheme)"
toggle:
icon: material/link
name: Switch to light mode
- media: "(prefers-color-scheme: light)" - media: "(prefers-color-scheme: light)"
scheme: default scheme: default
primary: white primary: white
toggle: toggle:
icon: material/toggle-switch icon: material/brightness-7
name: Switch to dark mode name: Switch to dark mode
- media: "(prefers-color-scheme: dark)" - media: "(prefers-color-scheme: dark)"
scheme: slate scheme: slate
primary: black primary: black
toggle: toggle:
icon: material/toggle-switch-off icon: material/brightness-4
name: Switch to system preference name: Switch to light mode
features: features:
# - navigation.instant # - navigation.instant
- navigation.tracking - navigation.tracking

View File

@@ -64,7 +64,7 @@ func (r Rule) IsValid() bool {
} }
} }
type DefaultRule struct { type _DefaultRule struct {
Inbound Listable[string] `json:"inbound,omitempty"` Inbound Listable[string] `json:"inbound,omitempty"`
IPVersion int `json:"ip_version,omitempty"` IPVersion int `json:"ip_version,omitempty"`
Network Listable[string] `json:"network,omitempty"` Network Listable[string] `json:"network,omitempty"`
@@ -104,6 +104,22 @@ type DefaultRule struct {
Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"` Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"`
} }
type DefaultRule _DefaultRule
func (r *DefaultRule) UnmarshalJSON(bytes []byte) error {
err := json.Unmarshal(bytes, (*_DefaultRule)(r))
if err != nil {
return err
}
//nolint:staticcheck
//goland:noinspection GoDeprecation
if r.Deprecated_RulesetIPCIDRMatchSource {
r.Deprecated_RulesetIPCIDRMatchSource = false
r.RuleSetIPCIDRMatchSource = true
}
return nil
}
func (r *DefaultRule) IsValid() bool { func (r *DefaultRule) IsValid() bool {
var defaultValue DefaultRule var defaultValue DefaultRule
defaultValue.Invert = r.Invert defaultValue.Invert = r.Invert

View File

@@ -64,7 +64,7 @@ func (r DNSRule) IsValid() bool {
} }
} }
type DefaultDNSRule struct { type _DefaultDNSRule struct {
Inbound Listable[string] `json:"inbound,omitempty"` Inbound Listable[string] `json:"inbound,omitempty"`
IPVersion int `json:"ip_version,omitempty"` IPVersion int `json:"ip_version,omitempty"`
QueryType Listable[DNSQueryType] `json:"query_type,omitempty"` QueryType Listable[DNSQueryType] `json:"query_type,omitempty"`
@@ -109,6 +109,22 @@ type DefaultDNSRule struct {
Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"` Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"`
} }
type DefaultDNSRule _DefaultDNSRule
func (r *DefaultDNSRule) UnmarshalJSON(bytes []byte) error {
err := json.UnmarshalDisallowUnknownFields(bytes, (*_DefaultDNSRule)(r))
if err != nil {
return err
}
//nolint:staticcheck
//goland:noinspection GoDeprecation
if r.Deprecated_RulesetIPCIDRMatchSource {
r.Deprecated_RulesetIPCIDRMatchSource = false
r.RuleSetIPCIDRMatchSource = true
}
return nil
}
func (r *DefaultDNSRule) IsValid() bool { func (r *DefaultDNSRule) IsValid() bool {
var defaultValue DefaultDNSRule var defaultValue DefaultDNSRule
defaultValue.Invert = r.Invert defaultValue.Invert = r.Invert

View File

@@ -48,6 +48,17 @@ func (r *RuleSet) UnmarshalJSON(bytes []byte) error {
if r.Tag == "" { if r.Tag == "" {
return E.New("missing tag") return E.New("missing tag")
} }
if r.Type != C.RuleSetTypeInline {
switch r.Format {
case "":
return E.New("missing format")
case C.RuleSetFormatSource, C.RuleSetFormatBinary:
default:
return E.New("unknown rule-set format: " + r.Format)
}
} else {
r.Format = ""
}
var v any var v any
switch r.Type { switch r.Type {
case "", C.RuleSetTypeInline: case "", C.RuleSetTypeInline:
@@ -60,17 +71,6 @@ func (r *RuleSet) UnmarshalJSON(bytes []byte) error {
default: default:
return E.New("unknown rule-set type: " + r.Type) return E.New("unknown rule-set type: " + r.Type)
} }
if r.Type != C.RuleSetTypeInline {
switch r.Format {
case "":
return E.New("missing format")
case C.RuleSetFormatSource, C.RuleSetFormatBinary:
default:
return E.New("unknown rule-set format: " + r.Format)
}
} else {
r.Format = ""
}
err = UnmarshallExcluded(bytes, (*_RuleSet)(r), v) err = UnmarshallExcluded(bytes, (*_RuleSet)(r), v)
if err != nil { if err != nil {
return err return err

View File

@@ -11,6 +11,11 @@ import (
) )
func New(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.Outbound) (adapter.Outbound, error) { func New(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.Outbound) (adapter.Outbound, error) {
var metadata *adapter.InboundContext
if tag != "" {
ctx, metadata = adapter.AppendContext(ctx)
metadata.Outbound = tag
}
if options.Type == "" { if options.Type == "" {
return nil, E.New("missing outbound type") return nil, E.New("missing outbound type")
} }

View File

@@ -70,7 +70,7 @@ func NewDirect(router adapter.Router, logger log.ContextLogger, tag string, opti
} }
func (h *Direct) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { func (h *Direct) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
ctx, metadata := adapter.ExtendContext(ctx) ctx, metadata := adapter.AppendContext(ctx)
metadata.Outbound = h.tag metadata.Outbound = h.tag
metadata.Destination = destination metadata.Destination = destination
switch h.overrideOption { switch h.overrideOption {
@@ -98,7 +98,7 @@ func (h *Direct) DialContext(ctx context.Context, network string, destination M.
} }
func (h *Direct) DialParallel(ctx context.Context, network string, destination M.Socksaddr, destinationAddresses []netip.Addr) (net.Conn, error) { func (h *Direct) DialParallel(ctx context.Context, network string, destination M.Socksaddr, destinationAddresses []netip.Addr) (net.Conn, error) {
ctx, metadata := adapter.ExtendContext(ctx) ctx, metadata := adapter.AppendContext(ctx)
metadata.Outbound = h.tag metadata.Outbound = h.tag
metadata.Destination = destination metadata.Destination = destination
switch h.overrideOption { switch h.overrideOption {

View File

@@ -54,7 +54,7 @@ func NewHTTP(ctx context.Context, router adapter.Router, logger log.ContextLogge
} }
func (h *HTTP) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { func (h *HTTP) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
ctx, metadata := adapter.ExtendContext(ctx) ctx, metadata := adapter.AppendContext(ctx)
metadata.Outbound = h.tag metadata.Outbound = h.tag
metadata.Destination = destination metadata.Destination = destination
h.logger.InfoContext(ctx, "outbound connection to ", destination) h.logger.InfoContext(ctx, "outbound connection to ", destination)

View File

@@ -79,7 +79,7 @@ func NewShadowsocks(ctx context.Context, router adapter.Router, logger log.Conte
} }
func (h *Shadowsocks) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { func (h *Shadowsocks) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
ctx, metadata := adapter.ExtendContext(ctx) ctx, metadata := adapter.AppendContext(ctx)
metadata.Outbound = h.tag metadata.Outbound = h.tag
metadata.Destination = destination metadata.Destination = destination
if h.multiplexDialer == nil { if h.multiplexDialer == nil {
@@ -107,7 +107,7 @@ func (h *Shadowsocks) DialContext(ctx context.Context, network string, destinati
} }
func (h *Shadowsocks) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { func (h *Shadowsocks) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
ctx, metadata := adapter.ExtendContext(ctx) ctx, metadata := adapter.AppendContext(ctx)
metadata.Outbound = h.tag metadata.Outbound = h.tag
metadata.Destination = destination metadata.Destination = destination
if h.multiplexDialer == nil { if h.multiplexDialer == nil {
@@ -149,7 +149,7 @@ var _ N.Dialer = (*shadowsocksDialer)(nil)
type shadowsocksDialer Shadowsocks type shadowsocksDialer Shadowsocks
func (h *shadowsocksDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { func (h *shadowsocksDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
ctx, metadata := adapter.ExtendContext(ctx) ctx, metadata := adapter.AppendContext(ctx)
metadata.Outbound = h.tag metadata.Outbound = h.tag
metadata.Destination = destination metadata.Destination = destination
switch N.NetworkName(network) { switch N.NetworkName(network) {
@@ -177,7 +177,7 @@ func (h *shadowsocksDialer) DialContext(ctx context.Context, network string, des
} }
func (h *shadowsocksDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { func (h *shadowsocksDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
ctx, metadata := adapter.ExtendContext(ctx) ctx, metadata := adapter.AppendContext(ctx)
metadata.Outbound = h.tag metadata.Outbound = h.tag
metadata.Destination = destination metadata.Destination = destination
outConn, err := h.dialer.DialContext(ctx, N.NetworkUDP, h.serverAddr) outConn, err := h.dialer.DialContext(ctx, N.NetworkUDP, h.serverAddr)

View File

@@ -92,7 +92,7 @@ func NewShadowTLS(ctx context.Context, router adapter.Router, logger log.Context
} }
func (h *ShadowTLS) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { func (h *ShadowTLS) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
ctx, metadata := adapter.ExtendContext(ctx) ctx, metadata := adapter.AppendContext(ctx)
metadata.Outbound = h.tag metadata.Outbound = h.tag
metadata.Destination = destination metadata.Destination = destination
switch N.NetworkName(network) { switch N.NetworkName(network) {

View File

@@ -65,7 +65,7 @@ func NewSocks(router adapter.Router, logger log.ContextLogger, tag string, optio
} }
func (h *Socks) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { func (h *Socks) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
ctx, metadata := adapter.ExtendContext(ctx) ctx, metadata := adapter.AppendContext(ctx)
metadata.Outbound = h.tag metadata.Outbound = h.tag
metadata.Destination = destination metadata.Destination = destination
switch N.NetworkName(network) { switch N.NetworkName(network) {
@@ -91,7 +91,7 @@ func (h *Socks) DialContext(ctx context.Context, network string, destination M.S
} }
func (h *Socks) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { func (h *Socks) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
ctx, metadata := adapter.ExtendContext(ctx) ctx, metadata := adapter.AppendContext(ctx)
metadata.Outbound = h.tag metadata.Outbound = h.tag
metadata.Destination = destination metadata.Destination = destination
if h.uotClient != nil { if h.uotClient != nil {

View File

@@ -124,7 +124,7 @@ func (h *Trojan) Close() error {
type trojanDialer Trojan type trojanDialer Trojan
func (h *trojanDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { func (h *trojanDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
ctx, metadata := adapter.ExtendContext(ctx) ctx, metadata := adapter.AppendContext(ctx)
metadata.Outbound = h.tag metadata.Outbound = h.tag
metadata.Destination = destination metadata.Destination = destination
var conn net.Conn var conn net.Conn

View File

@@ -143,7 +143,7 @@ func (h *VLESS) Close() error {
type vlessDialer VLESS type vlessDialer VLESS
func (h *vlessDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { func (h *vlessDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
ctx, metadata := adapter.ExtendContext(ctx) ctx, metadata := adapter.AppendContext(ctx)
metadata.Outbound = h.tag metadata.Outbound = h.tag
metadata.Destination = destination metadata.Destination = destination
var conn net.Conn var conn net.Conn
@@ -186,7 +186,7 @@ func (h *vlessDialer) DialContext(ctx context.Context, network string, destinati
func (h *vlessDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { func (h *vlessDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
h.logger.InfoContext(ctx, "outbound packet connection to ", destination) h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
ctx, metadata := adapter.ExtendContext(ctx) ctx, metadata := adapter.AppendContext(ctx)
metadata.Outbound = h.tag metadata.Outbound = h.tag
metadata.Destination = destination metadata.Destination = destination
var conn net.Conn var conn net.Conn

View File

@@ -157,7 +157,7 @@ func (h *VMess) NewPacketConnection(ctx context.Context, conn N.PacketConn, meta
type vmessDialer VMess type vmessDialer VMess
func (h *vmessDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { func (h *vmessDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
ctx, metadata := adapter.ExtendContext(ctx) ctx, metadata := adapter.AppendContext(ctx)
metadata.Outbound = h.tag metadata.Outbound = h.tag
metadata.Destination = destination metadata.Destination = destination
var conn net.Conn var conn net.Conn
@@ -185,7 +185,7 @@ func (h *vmessDialer) DialContext(ctx context.Context, network string, destinati
} }
func (h *vmessDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { func (h *vmessDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
ctx, metadata := adapter.ExtendContext(ctx) ctx, metadata := adapter.AppendContext(ctx)
metadata.Outbound = h.tag metadata.Outbound = h.tag
metadata.Destination = destination metadata.Destination = destination
var conn net.Conn var conn net.Conn

View File

@@ -153,14 +153,14 @@ func NewRouter(
Logger: router.dnsLogger, Logger: router.dnsLogger,
}) })
for i, ruleOptions := range options.Rules { for i, ruleOptions := range options.Rules {
routeRule, err := NewRule(ctx, router, router.logger, ruleOptions, true) routeRule, err := NewRule(router, router.logger, ruleOptions, true)
if err != nil { if err != nil {
return nil, E.Cause(err, "parse rule[", i, "]") return nil, E.Cause(err, "parse rule[", i, "]")
} }
router.rules = append(router.rules, routeRule) router.rules = append(router.rules, routeRule)
} }
for i, dnsRuleOptions := range dnsOptions.Rules { for i, dnsRuleOptions := range dnsOptions.Rules {
dnsRule, err := NewDNSRule(ctx, router, router.logger, dnsRuleOptions, true) dnsRule, err := NewDNSRule(router, router.logger, dnsRuleOptions, true)
if err != nil { if err != nil {
return nil, E.Cause(err, "parse dns rule[", i, "]") return nil, E.Cause(err, "parse dns rule[", i, "]")
} }
@@ -338,7 +338,6 @@ func NewRouter(
_ = router.interfaceFinder.Update() _ = router.interfaceFinder.Update()
}) })
interfaceMonitor, err := tun.NewDefaultInterfaceMonitor(router.networkMonitor, router.logger, tun.DefaultInterfaceMonitorOptions{ interfaceMonitor, err := tun.NewDefaultInterfaceMonitor(router.networkMonitor, router.logger, tun.DefaultInterfaceMonitorOptions{
InterfaceFinder: router.interfaceFinder,
OverrideAndroidVPN: options.OverrideAndroidVPN, OverrideAndroidVPN: options.OverrideAndroidVPN,
UnderNetworkExtension: platformInterface != nil && platformInterface.UnderNetworkExtension(), UnderNetworkExtension: platformInterface != nil && platformInterface.UnderNetworkExtension(),
}) })
@@ -659,15 +658,14 @@ func (r *Router) Close() error {
func (r *Router) PostStart() error { func (r *Router) PostStart() error {
monitor := taskmonitor.New(r.logger, C.StopTimeout) monitor := taskmonitor.New(r.logger, C.StopTimeout)
var cacheContext *adapter.HTTPStartContext
if len(r.ruleSets) > 0 { if len(r.ruleSets) > 0 {
monitor.Start("initialize rule-set") monitor.Start("initialize rule-set")
cacheContext = adapter.NewHTTPStartContext() ruleSetStartContext := NewRuleSetStartContext()
var ruleSetStartGroup task.Group var ruleSetStartGroup task.Group
for i, ruleSet := range r.ruleSets { for i, ruleSet := range r.ruleSets {
ruleSetInPlace := ruleSet ruleSetInPlace := ruleSet
ruleSetStartGroup.Append0(func(ctx context.Context) error { ruleSetStartGroup.Append0(func(ctx context.Context) error {
err := ruleSetInPlace.StartContext(ctx, cacheContext) err := ruleSetInPlace.StartContext(ctx, ruleSetStartContext)
if err != nil { if err != nil {
return E.Cause(err, "initialize rule-set[", i, "]") return E.Cause(err, "initialize rule-set[", i, "]")
} }
@@ -681,9 +679,7 @@ func (r *Router) PostStart() error {
if err != nil { if err != nil {
return err return err
} }
} ruleSetStartContext.Close()
if cacheContext != nil {
cacheContext.Close()
} }
needFindProcess := r.needFindProcess needFindProcess := r.needFindProcess
needWIFIState := r.needWIFIState needWIFIState := r.needWIFIState

View File

@@ -13,7 +13,6 @@ import (
"github.com/sagernet/sing-box/common/geoip" "github.com/sagernet/sing-box/common/geoip"
"github.com/sagernet/sing-box/common/geosite" "github.com/sagernet/sing-box/common/geosite"
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/experimental/deprecated"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata" M "github.com/sagernet/sing/common/metadata"
"github.com/sagernet/sing/common/rw" "github.com/sagernet/sing/common/rw"
@@ -33,7 +32,7 @@ func (r *Router) LoadGeosite(code string) (adapter.Rule, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
rule, err = NewDefaultRule(r.ctx, r, nil, geosite.Compile(items)) rule, err = NewDefaultRule(r, nil, geosite.Compile(items))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -42,7 +41,6 @@ func (r *Router) LoadGeosite(code string) (adapter.Rule, error) {
} }
func (r *Router) prepareGeoIPDatabase() error { func (r *Router) prepareGeoIPDatabase() error {
deprecated.Report(r.ctx, deprecated.OptionGEOIP)
var geoPath string var geoPath string
if r.geoIPOptions.Path != "" { if r.geoIPOptions.Path != "" {
geoPath = r.geoIPOptions.Path geoPath = r.geoIPOptions.Path
@@ -89,7 +87,6 @@ func (r *Router) prepareGeoIPDatabase() error {
} }
func (r *Router) prepareGeositeDatabase() error { func (r *Router) prepareGeositeDatabase() error {
deprecated.Report(r.ctx, deprecated.OptionGEOSITE)
var geoPath string var geoPath string
if r.geositeOptions.Path != "" { if r.geositeOptions.Path != "" {
geoPath = r.geositeOptions.Path geoPath = r.geositeOptions.Path

View File

@@ -1,17 +1,14 @@
package route package route
import ( import (
"context"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/experimental/deprecated"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
) )
func NewRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.Rule, checkOutbound bool) (adapter.Rule, error) { func NewRule(router adapter.Router, logger log.ContextLogger, options option.Rule, checkOutbound bool) (adapter.Rule, error) {
switch options.Type { switch options.Type {
case "", C.RuleTypeDefault: case "", C.RuleTypeDefault:
if !options.DefaultOptions.IsValid() { if !options.DefaultOptions.IsValid() {
@@ -20,7 +17,7 @@ func NewRule(ctx context.Context, router adapter.Router, logger log.ContextLogge
if options.DefaultOptions.Outbound == "" && checkOutbound { if options.DefaultOptions.Outbound == "" && checkOutbound {
return nil, E.New("missing outbound field") return nil, E.New("missing outbound field")
} }
return NewDefaultRule(ctx, router, logger, options.DefaultOptions) return NewDefaultRule(router, logger, options.DefaultOptions)
case C.RuleTypeLogical: case C.RuleTypeLogical:
if !options.LogicalOptions.IsValid() { if !options.LogicalOptions.IsValid() {
return nil, E.New("missing conditions") return nil, E.New("missing conditions")
@@ -28,7 +25,7 @@ func NewRule(ctx context.Context, router adapter.Router, logger log.ContextLogge
if options.LogicalOptions.Outbound == "" && checkOutbound { if options.LogicalOptions.Outbound == "" && checkOutbound {
return nil, E.New("missing outbound field") return nil, E.New("missing outbound field")
} }
return NewLogicalRule(ctx, router, logger, options.LogicalOptions) return NewLogicalRule(router, logger, options.LogicalOptions)
default: default:
return nil, E.New("unknown rule type: ", options.Type) return nil, E.New("unknown rule type: ", options.Type)
} }
@@ -45,7 +42,7 @@ type RuleItem interface {
String() string String() string
} }
func NewDefaultRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.DefaultRule) (*DefaultRule, error) { func NewDefaultRule(router adapter.Router, logger log.ContextLogger, options option.DefaultRule) (*DefaultRule, error) {
rule := &DefaultRule{ rule := &DefaultRule{
abstractDefaultRule{ abstractDefaultRule{
invert: options.Invert, invert: options.Invert,
@@ -221,16 +218,7 @@ func NewDefaultRule(ctx context.Context, router adapter.Router, logger log.Conte
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
if len(options.RuleSet) > 0 { if len(options.RuleSet) > 0 {
var matchSource bool item := NewRuleSetItem(router, options.RuleSet, options.RuleSetIPCIDRMatchSource, false)
if options.RuleSetIPCIDRMatchSource {
matchSource = true
} else
//nolint:staticcheck
if options.Deprecated_RulesetIPCIDRMatchSource {
matchSource = true
deprecated.Report(ctx, deprecated.OptionBadMatchSource)
}
item := NewRuleSetItem(router, options.RuleSet, matchSource, false)
rule.items = append(rule.items, item) rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
@@ -243,7 +231,7 @@ type LogicalRule struct {
abstractLogicalRule abstractLogicalRule
} }
func NewLogicalRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.LogicalRule) (*LogicalRule, error) { func NewLogicalRule(router adapter.Router, logger log.ContextLogger, options option.LogicalRule) (*LogicalRule, error) {
r := &LogicalRule{ r := &LogicalRule{
abstractLogicalRule{ abstractLogicalRule{
rules: make([]adapter.HeadlessRule, len(options.Rules)), rules: make([]adapter.HeadlessRule, len(options.Rules)),
@@ -260,7 +248,7 @@ func NewLogicalRule(ctx context.Context, router adapter.Router, logger log.Conte
return nil, E.New("unknown logical mode: ", options.Mode) return nil, E.New("unknown logical mode: ", options.Mode)
} }
for i, subRule := range options.Rules { for i, subRule := range options.Rules {
rule, err := NewRule(ctx, router, logger, subRule, false) rule, err := NewRule(router, logger, subRule, false)
if err != nil { if err != nil {
return nil, E.Cause(err, "sub rule[", i, "]") return nil, E.Cause(err, "sub rule[", i, "]")
} }

View File

@@ -1,19 +1,17 @@
package route package route
import ( import (
"context"
"net/netip" "net/netip"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/experimental/deprecated"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
) )
func NewDNSRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.DNSRule, checkServer bool) (adapter.DNSRule, error) { func NewDNSRule(router adapter.Router, logger log.ContextLogger, options option.DNSRule, checkServer bool) (adapter.DNSRule, error) {
switch options.Type { switch options.Type {
case "", C.RuleTypeDefault: case "", C.RuleTypeDefault:
if !options.DefaultOptions.IsValid() { if !options.DefaultOptions.IsValid() {
@@ -22,7 +20,7 @@ func NewDNSRule(ctx context.Context, router adapter.Router, logger log.ContextLo
if options.DefaultOptions.Server == "" && checkServer { if options.DefaultOptions.Server == "" && checkServer {
return nil, E.New("missing server field") return nil, E.New("missing server field")
} }
return NewDefaultDNSRule(ctx, router, logger, options.DefaultOptions) return NewDefaultDNSRule(router, logger, options.DefaultOptions)
case C.RuleTypeLogical: case C.RuleTypeLogical:
if !options.LogicalOptions.IsValid() { if !options.LogicalOptions.IsValid() {
return nil, E.New("missing conditions") return nil, E.New("missing conditions")
@@ -30,7 +28,7 @@ func NewDNSRule(ctx context.Context, router adapter.Router, logger log.ContextLo
if options.LogicalOptions.Server == "" && checkServer { if options.LogicalOptions.Server == "" && checkServer {
return nil, E.New("missing server field") return nil, E.New("missing server field")
} }
return NewLogicalDNSRule(ctx, router, logger, options.LogicalOptions) return NewLogicalDNSRule(router, logger, options.LogicalOptions)
default: default:
return nil, E.New("unknown rule type: ", options.Type) return nil, E.New("unknown rule type: ", options.Type)
} }
@@ -45,7 +43,7 @@ type DefaultDNSRule struct {
clientSubnet *netip.Prefix clientSubnet *netip.Prefix
} }
func NewDefaultDNSRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.DefaultDNSRule) (*DefaultDNSRule, error) { func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options option.DefaultDNSRule) (*DefaultDNSRule, error) {
rule := &DefaultDNSRule{ rule := &DefaultDNSRule{
abstractDefaultRule: abstractDefaultRule{ abstractDefaultRule: abstractDefaultRule{
invert: options.Invert, invert: options.Invert,
@@ -229,16 +227,7 @@ func NewDefaultDNSRule(ctx context.Context, router adapter.Router, logger log.Co
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
if len(options.RuleSet) > 0 { if len(options.RuleSet) > 0 {
var matchSource bool item := NewRuleSetItem(router, options.RuleSet, options.RuleSetIPCIDRMatchSource, options.RuleSetIPCIDRAcceptEmpty)
if options.RuleSetIPCIDRMatchSource {
matchSource = true
} else
//nolint:staticcheck
if options.Deprecated_RulesetIPCIDRMatchSource {
matchSource = true
deprecated.Report(ctx, deprecated.OptionBadMatchSource)
}
item := NewRuleSetItem(router, options.RuleSet, matchSource, options.RuleSetIPCIDRAcceptEmpty)
rule.items = append(rule.items, item) rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item) rule.allItems = append(rule.allItems, item)
} }
@@ -294,7 +283,7 @@ type LogicalDNSRule struct {
clientSubnet *netip.Prefix clientSubnet *netip.Prefix
} }
func NewLogicalDNSRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.LogicalDNSRule) (*LogicalDNSRule, error) { func NewLogicalDNSRule(router adapter.Router, logger log.ContextLogger, options option.LogicalDNSRule) (*LogicalDNSRule, error) {
r := &LogicalDNSRule{ r := &LogicalDNSRule{
abstractLogicalRule: abstractLogicalRule{ abstractLogicalRule: abstractLogicalRule{
rules: make([]adapter.HeadlessRule, len(options.Rules)), rules: make([]adapter.HeadlessRule, len(options.Rules)),
@@ -314,7 +303,7 @@ func NewLogicalDNSRule(ctx context.Context, router adapter.Router, logger log.Co
return nil, E.New("unknown logical mode: ", options.Mode) return nil, E.New("unknown logical mode: ", options.Mode)
} }
for i, subRule := range options.Rules { for i, subRule := range options.Rules {
rule, err := NewDNSRule(ctx, router, logger, subRule, false) rule, err := NewDNSRule(router, logger, subRule, false)
if err != nil { if err != nil {
return nil, E.Cause(err, "sub rule[", i, "]") return nil, E.Cause(err, "sub rule[", i, "]")
} }

View File

@@ -2,6 +2,9 @@ package route
import ( import (
"context" "context"
"net"
"net/http"
"sync"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
@@ -9,6 +12,8 @@ import (
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger" "github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"go4.org/netipx" "go4.org/netipx"
) )
@@ -41,3 +46,43 @@ func extractIPSetFromRule(rawRule adapter.HeadlessRule) []*netipx.IPSet {
panic("unexpected rule type") panic("unexpected rule type")
} }
} }
var _ adapter.RuleSetStartContext = (*RuleSetStartContext)(nil)
type RuleSetStartContext struct {
access sync.Mutex
httpClientCache map[string]*http.Client
}
func NewRuleSetStartContext() *RuleSetStartContext {
return &RuleSetStartContext{
httpClientCache: make(map[string]*http.Client),
}
}
func (c *RuleSetStartContext) HTTPClient(detour string, dialer N.Dialer) *http.Client {
c.access.Lock()
defer c.access.Unlock()
if httpClient, loaded := c.httpClientCache[detour]; loaded {
return httpClient
}
httpClient := &http.Client{
Transport: &http.Transport{
ForceAttemptHTTP2: true,
TLSHandshakeTimeout: C.TCPTimeout,
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
},
},
}
c.httpClientCache[detour] = httpClient
return httpClient
}
func (c *RuleSetStartContext) Close() {
c.access.Lock()
defer c.access.Unlock()
for _, client := range c.httpClientCache {
client.CloseIdleConnections()
}
}

View File

@@ -58,6 +58,7 @@ func NewLocalRuleSet(ctx context.Context, router adapter.Router, logger logger.L
} }
} }
if options.Type == C.RuleSetTypeLocal { if options.Type == C.RuleSetTypeLocal {
var watcher *fswatch.Watcher
filePath, _ := filepath.Abs(options.LocalOptions.Path) filePath, _ := filepath.Abs(options.LocalOptions.Path)
watcher, err := fswatch.NewWatcher(fswatch.Options{ watcher, err := fswatch.NewWatcher(fswatch.Options{
Path: []string{filePath}, Path: []string{filePath},
@@ -84,7 +85,7 @@ func (s *LocalRuleSet) String() string {
return strings.Join(F.MapToString(s.rules), " ") return strings.Join(F.MapToString(s.rules), " ")
} }
func (s *LocalRuleSet) StartContext(ctx context.Context, startContext *adapter.HTTPStartContext) error { func (s *LocalRuleSet) StartContext(ctx context.Context, startContext adapter.RuleSetStartContext) error {
if s.watcher != nil { if s.watcher != nil {
err := s.watcher.Start() err := s.watcher.Start()
if err != nil { if err != nil {

View File

@@ -45,7 +45,6 @@ type RemoteRuleSet struct {
lastUpdated time.Time lastUpdated time.Time
lastEtag string lastEtag string
updateTicker *time.Ticker updateTicker *time.Ticker
cacheFile adapter.CacheFile
pauseManager pause.Manager pauseManager pause.Manager
callbackAccess sync.Mutex callbackAccess sync.Mutex
callbacks list.List[adapter.RuleSetUpdateCallback] callbacks list.List[adapter.RuleSetUpdateCallback]
@@ -67,7 +66,6 @@ func NewRemoteRuleSet(ctx context.Context, router adapter.Router, logger logger.
logger: logger, logger: logger,
options: options, options: options,
updateInterval: updateInterval, updateInterval: updateInterval,
cacheFile: service.FromContext[adapter.CacheFile](ctx),
pauseManager: service.FromContext[pause.Manager](ctx), pauseManager: service.FromContext[pause.Manager](ctx),
} }
} }
@@ -80,7 +78,7 @@ func (s *RemoteRuleSet) String() string {
return strings.Join(F.MapToString(s.rules), " ") return strings.Join(F.MapToString(s.rules), " ")
} }
func (s *RemoteRuleSet) StartContext(ctx context.Context, startContext *adapter.HTTPStartContext) error { func (s *RemoteRuleSet) StartContext(ctx context.Context, startContext adapter.RuleSetStartContext) error {
var dialer N.Dialer var dialer N.Dialer
if s.options.RemoteOptions.DownloadDetour != "" { if s.options.RemoteOptions.DownloadDetour != "" {
outbound, loaded := s.router.Outbound(s.options.RemoteOptions.DownloadDetour) outbound, loaded := s.router.Outbound(s.options.RemoteOptions.DownloadDetour)
@@ -96,8 +94,9 @@ func (s *RemoteRuleSet) StartContext(ctx context.Context, startContext *adapter.
dialer = outbound dialer = outbound
} }
s.dialer = dialer s.dialer = dialer
if s.cacheFile != nil { cacheFile := service.FromContext[adapter.CacheFile](s.ctx)
if savedSet := s.cacheFile.LoadRuleSet(s.options.Tag); savedSet != nil { if cacheFile != nil {
if savedSet := cacheFile.LoadRuleSet(s.options.Tag); savedSet != nil {
err := s.loadBytes(savedSet.Content) err := s.loadBytes(savedSet.Content)
if err != nil { if err != nil {
return E.Cause(err, "restore cached rule-set") return E.Cause(err, "restore cached rule-set")
@@ -227,7 +226,7 @@ func (s *RemoteRuleSet) loopUpdate() {
} }
} }
func (s *RemoteRuleSet) fetchOnce(ctx context.Context, startContext *adapter.HTTPStartContext) error { func (s *RemoteRuleSet) fetchOnce(ctx context.Context, startContext adapter.RuleSetStartContext) error {
s.logger.Debug("updating rule-set ", s.options.Tag, " from URL: ", s.options.RemoteOptions.URL) s.logger.Debug("updating rule-set ", s.options.Tag, " from URL: ", s.options.RemoteOptions.URL)
var httpClient *http.Client var httpClient *http.Client
if startContext != nil { if startContext != nil {
@@ -258,11 +257,12 @@ func (s *RemoteRuleSet) fetchOnce(ctx context.Context, startContext *adapter.HTT
case http.StatusOK: case http.StatusOK:
case http.StatusNotModified: case http.StatusNotModified:
s.lastUpdated = time.Now() s.lastUpdated = time.Now()
if s.cacheFile != nil { cacheFile := service.FromContext[adapter.CacheFile](s.ctx)
savedRuleSet := s.cacheFile.LoadRuleSet(s.options.Tag) if cacheFile != nil {
savedRuleSet := cacheFile.LoadRuleSet(s.options.Tag)
if savedRuleSet != nil { if savedRuleSet != nil {
savedRuleSet.LastUpdated = s.lastUpdated savedRuleSet.LastUpdated = s.lastUpdated
err = s.cacheFile.SaveRuleSet(s.options.Tag, savedRuleSet) err = cacheFile.SaveRuleSet(s.options.Tag, savedRuleSet)
if err != nil { if err != nil {
s.logger.Error("save rule-set updated time: ", err) s.logger.Error("save rule-set updated time: ", err)
return nil return nil
@@ -290,8 +290,9 @@ func (s *RemoteRuleSet) fetchOnce(ctx context.Context, startContext *adapter.HTT
s.lastEtag = eTagHeader s.lastEtag = eTagHeader
} }
s.lastUpdated = time.Now() s.lastUpdated = time.Now()
if s.cacheFile != nil { cacheFile := service.FromContext[adapter.CacheFile](s.ctx)
err = s.cacheFile.SaveRuleSet(s.options.Tag, &adapter.SavedRuleSet{ if cacheFile != nil {
err = cacheFile.SaveRuleSet(s.options.Tag, &adapter.SavedRuleSet{
LastUpdated: s.lastUpdated, LastUpdated: s.lastUpdated,
Content: content, Content: content,
LastEtag: s.lastEtag, LastEtag: s.lastEtag,