Compare commits

..

52 Commits

Author SHA1 Message Date
世界
7d263eb733 documentation: Update changelog 2023-06-14 16:28:44 +08:00
世界
222687d9c5 Update goreleaser usage 2023-06-14 09:39:13 +08:00
世界
07d3652e30 Build with_dhcp by default 2023-06-14 09:14:45 +08:00
世界
8d5b9d240a Fix outbound start sequence 2023-06-13 22:38:05 +08:00
世界
4f12eba944 Fix hysteria outbound 2023-06-13 21:41:33 +08:00
世界
a7f77d59c1 Update documentation 2023-06-11 22:38:37 +08:00
shadow750d6
597248130f Reconnect once if hysteria request fails
This allows graceful recovery when network isn't good enough.

[Original hysteria source
code](13d46da998/core/cs/client.go (L182))
has similar mechanism.
2023-06-11 22:21:32 +08:00
世界
3c2c9cf317 Migrate gVisor to fork 2023-06-11 22:07:36 +08:00
世界
e572b9d0cd Update dependencies 2023-06-11 20:58:59 +08:00
世界
52e9059a8d Fix fakeip routing 2023-06-11 20:58:59 +08:00
世界
0cb9cff690 Fix shadowsocks none client 2023-06-08 10:23:39 +08:00
世界
c0669cb2a5 Fix TLS 1.2 support for shadow-tls client 2023-06-07 21:03:39 +08:00
世界
c5902f2473 Fix using v2ray websocket transport with detour 2023-06-07 21:03:21 +08:00
世界
22028602e8 Improve read waiter interface 2023-06-07 21:03:11 +08:00
世界
bd54608473 Fix DNS outbound 2023-06-07 21:03:08 +08:00
世界
3741394269 Add cache_id option for Clash cache file 2023-06-07 21:03:06 +08:00
世界
6266d2df7e Fix shadowsocks AEAD UDP server 2023-06-07 21:02:52 +08:00
世界
01dfba722a Use API to create windows firewall rule 2023-06-07 21:01:29 +08:00
世界
f8d5f01665 Reimplemented shadowsocks client 2023-06-07 20:57:07 +08:00
Hellojack
ad999d4791 Fix UVariantLen usage 2023-06-07 20:56:57 +08:00
世界
6f1b258501 Improve DNS caching 2023-06-07 20:56:55 +08:00
世界
f949ddc0ab Set TCP keepalive for WireGuard gVisor TCP connections 2023-06-07 20:53:26 +08:00
Weltolk
f53007cbf3 documentation: Fix fakeip link broken 2023-06-07 20:53:13 +08:00
世界
c287731df9 Improve direct copy 2023-06-07 20:53:00 +08:00
世界
bc32c78d03 Improve multiplex 2023-06-07 20:46:34 +08:00
世界
daee0db7bb clash-api: Reset outbounds in DELETE /connections 2023-06-07 20:45:39 +08:00
世界
91fbf4c79b Add multiplexer for VLESS outbound 2023-06-07 20:45:39 +08:00
世界
54d9ef2f2a Update gVisor to 20230417.0 2023-06-07 20:45:25 +08:00
世界
e056d4502b Add debug http server 2023-06-07 20:45:25 +08:00
世界
98c2c439aa Add filemanager api 2023-06-07 20:45:25 +08:00
世界
b6068cea6b Update wireguard-go 2023-06-07 20:38:30 +08:00
世界
9c9affa719 Ignore system tun stack bind interface error 2023-06-07 20:35:02 +08:00
世界
8eb7dd0059 Improve VLESS request 2023-06-07 20:35:00 +08:00
世界
a62ad44883 Add deadline interface 2023-06-07 20:34:56 +08:00
世界
2850354070 shadowsocks: Multi-user support for legacy AEAD inbound
Signed-off-by: wwqgtxx <wwqgtxx@gmail.com>
2023-06-07 20:34:54 +08:00
世界
0a4abcbbc8 Add headers option for HTTP outbound 2023-06-07 20:34:52 +08:00
世界
b491c350ae URLTest improvements 2023-06-07 20:33:56 +08:00
世界
1fbe7c54bf Fix wireguard reconnect 2023-06-07 20:33:53 +08:00
世界
9d32fc9bd1 Use HTTPS URLTest source 2023-06-07 20:33:50 +08:00
世界
542612129d clash-api: Add Clash.Meta APIs 2023-06-07 20:33:41 +08:00
世界
750f87bb0a clash api: download clash-dashboard if external-ui directory is empty 2023-06-07 20:33:06 +08:00
世界
e168de79c7 Add multi-peer support for wireguard outbound 2023-06-07 20:33:04 +08:00
世界
9bca5a517f Add fakeip support 2023-06-07 20:31:26 +08:00
世界
aa94cfb876 Refactor rules 2023-06-07 20:28:21 +08:00
世界
52b776b561 Add dns reverse mapping 2023-06-07 20:19:46 +08:00
世界
c74d3a53d4 documentation: Update changelog 2023-05-19 15:48:35 +08:00
世界
fe7ac80a6c Update dependencies 2023-05-19 15:48:35 +08:00
世界
e50b334b9a Fix uTLS ALPN 2023-05-19 15:41:18 +08:00
XYenon
a0d8e374fb Fix incorrect use of sort.Slice 2023-05-19 15:40:48 +08:00
Larvan2
d3a67cb5ae Enable mkdocs search in documentation
Signed-off-by: Larvan2 <78135608+Larvan2@users.noreply.github.com>
2023-05-19 15:40:42 +08:00
世界
e69e98b185 Fix documentation 2023-05-19 15:40:13 +08:00
世界
5e1499d67b Update badtls 2023-05-19 15:39:40 +08:00
54 changed files with 415 additions and 967 deletions

View File

@@ -14,6 +14,7 @@ builds:
tags: tags:
- with_gvisor - with_gvisor
- with_quic - with_quic
- with_dhcp
- with_wireguard - with_wireguard
- with_utls - with_utls
- with_reality_server - with_reality_server
@@ -48,6 +49,7 @@ builds:
tags: tags:
- with_gvisor - with_gvisor
- with_quic - with_quic
- with_dhcp
- with_wireguard - with_wireguard
- with_utls - with_utls
- with_clash_api - with_clash_api

View File

@@ -9,7 +9,7 @@ RUN set -ex \
&& apk add git build-base \ && apk add git build-base \
&& export COMMIT=$(git rev-parse --short HEAD) \ && export COMMIT=$(git rev-parse --short HEAD) \
&& export VERSION=$(go run ./cmd/internal/read_tag) \ && export VERSION=$(go run ./cmd/internal/read_tag) \
&& go build -v -trimpath -tags with_gvisor,with_quic,with_wireguard,with_utls,with_reality_server,with_clash_api,with_acme \ && go build -v -trimpath -tags with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_reality_server,with_clash_api,with_acme \
-o /go/bin/sing-box \ -o /go/bin/sing-box \
-ldflags "-X \"github.com/sagernet/sing-box/constant.Version=$VERSION\" -s -w -buildid=" \ -ldflags "-X \"github.com/sagernet/sing-box/constant.Version=$VERSION\" -s -w -buildid=" \
./cmd/sing-box ./cmd/sing-box

View File

@@ -1,6 +1,6 @@
NAME = sing-box NAME = sing-box
COMMIT = $(shell git rev-parse --short HEAD) COMMIT = $(shell git rev-parse --short HEAD)
TAGS ?= with_gvisor,with_quic,with_wireguard,with_utls,with_reality_server,with_clash_api TAGS ?= with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_reality_server,with_clash_api
TAGS_TEST ?= with_gvisor,with_quic,with_wireguard,with_grpc,with_ech,with_utls,with_reality_server,with_shadowsocksr TAGS_TEST ?= with_gvisor,with_quic,with_wireguard,with_grpc,with_ech,with_utls,with_reality_server,with_shadowsocksr
GOHOSTOS = $(shell go env GOHOSTOS) GOHOSTOS = $(shell go env GOHOSTOS)
@@ -48,14 +48,14 @@ proto_install:
go install -v google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest go install -v google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
snapshot: snapshot:
go run ./cmd/internal/build goreleaser release --rm-dist --snapshot || exit 1 go run ./cmd/internal/build goreleaser release --clean --snapshot || exit 1
mkdir dist/release mkdir dist/release
mv dist/*.tar.gz dist/*.zip dist/*.deb dist/*.rpm dist/release mv dist/*.tar.gz dist/*.zip dist/*.deb dist/*.rpm dist/release
ghr --delete --draft --prerelease -p 1 nightly dist/release ghr --delete --draft --prerelease -p 1 nightly dist/release
rm -r dist rm -r dist
release: release:
go run ./cmd/internal/build goreleaser release --rm-dist --skip-publish || exit 1 go run ./cmd/internal/build goreleaser release --clean --skip-publish || exit 1
mkdir dist/release mkdir dist/release
mv dist/*.tar.gz dist/*.zip dist/*.deb dist/*.rpm dist/release mv dist/*.tar.gz dist/*.zip dist/*.deb dist/*.rpm dist/release
ghr --delete --draft --prerelease -p 3 $(shell git describe --tags) dist/release ghr --delete --draft --prerelease -p 3 $(shell git describe --tags) dist/release

View File

@@ -21,3 +21,8 @@ type FakeIPStorage interface {
FakeIPLoad(address netip.Addr) (string, bool) FakeIPLoad(address netip.Addr) (string, bool)
FakeIPReset() error FakeIPReset() error
} }
type FakeIPTransport interface {
dns.Transport
Store() FakeIPStore
}

View File

@@ -46,6 +46,7 @@ type InboundContext struct {
SourceGeoIPCode string SourceGeoIPCode string
GeoIPCode string GeoIPCode string
ProcessInfo *process.Info ProcessInfo *process.Info
FakeIP bool
// dns cache // dns cache

View File

@@ -4,7 +4,6 @@ import (
"context" "context"
"net" "net"
"github.com/sagernet/sing-tun"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
) )
@@ -14,12 +13,8 @@ type Outbound interface {
Type() string Type() string
Tag() string Tag() string
Network() []string Network() []string
Dependencies() []string
N.Dialer N.Dialer
NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
} }
type IPOutbound interface {
Outbound
NewIPConnection(ctx context.Context, conn tun.RouteContext, metadata InboundContext) (tun.DirectDestination, error)
}

View File

@@ -25,9 +25,6 @@ type Router interface {
RouteConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error RouteConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
RouteIPConnection(ctx context.Context, conn tun.RouteContext, metadata InboundContext) tun.RouteAction
NatRequired(outbound string) bool
GeoIPReader() *geoip.Reader GeoIPReader() *geoip.Reader
LoadGeosite(code string) (Rule, error) LoadGeosite(code string) (Rule, error)
@@ -45,9 +42,7 @@ type Router interface {
NetworkMonitor() tun.NetworkUpdateMonitor NetworkMonitor() tun.NetworkUpdateMonitor
InterfaceMonitor() tun.DefaultInterfaceMonitor InterfaceMonitor() tun.DefaultInterfaceMonitor
PackageManager() tun.PackageManager PackageManager() tun.PackageManager
Rules() []Rule Rules() []Rule
IPRules() []IPRule
TimeService TimeService
@@ -89,11 +84,6 @@ type DNSRule interface {
RewriteTTL() *uint32 RewriteTTL() *uint32
} }
type IPRule interface {
Rule
Action() tun.ActionType
}
type InterfaceUpdateListener interface { type InterfaceUpdateListener interface {
InterfaceUpdated() error InterfaceUpdated() error
} }

17
box.go
View File

@@ -217,20 +217,9 @@ func (s *Box) preStart() error {
return E.Cause(err, "pre-starting ", serviceName) return E.Cause(err, "pre-starting ", serviceName)
} }
} }
for i, out := range s.outbounds { err := s.startOutbounds()
var tag string if err != nil {
if out.Tag() == "" { return err
tag = F.ToString(i)
} else {
tag = out.Tag()
}
if starter, isStarter := out.(common.Starter); isStarter {
s.logger.Trace("initializing outbound/", out.Type(), "[", tag, "]")
err := starter.Start()
if err != nil {
return E.Cause(err, "initialize outbound/", out.Type(), "[", tag, "]")
}
}
} }
return s.router.Start() return s.router.Start()
} }

76
box_outbound.go Normal file
View File

@@ -0,0 +1,76 @@
package box
import (
"strings"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
)
func (s *Box) startOutbounds() error {
outboundTags := make(map[adapter.Outbound]string)
outbounds := make(map[string]adapter.Outbound)
for i, outboundToStart := range s.outbounds {
var outboundTag string
if outboundToStart.Tag() == "" {
outboundTag = F.ToString(i)
} else {
outboundTag = outboundToStart.Tag()
}
outboundTags[outboundToStart] = outboundTag
outbounds[outboundTag] = outboundToStart
}
started := make(map[string]bool)
for {
canContinue := false
startOne:
for _, outboundToStart := range s.outbounds {
outboundTag := outboundTags[outboundToStart]
if started[outboundTag] {
continue
}
dependencies := outboundToStart.Dependencies()
for _, dependency := range dependencies {
if !started[dependency] {
continue startOne
}
}
started[outboundTag] = true
canContinue = true
if starter, isStarter := outboundToStart.(common.Starter); isStarter {
s.logger.Trace("initializing outbound/", outboundToStart.Type(), "[", outboundTag, "]")
err := starter.Start()
if err != nil {
return E.Cause(err, "initialize outbound/", outboundToStart.Type(), "[", outboundTag, "]")
}
}
}
if len(started) == len(s.outbounds) {
break
}
if canContinue {
continue
}
currentOutbound := common.Find(s.outbounds, func(it adapter.Outbound) bool {
return !started[outboundTags[it]]
})
var lintOutbound func(oTree []string, oCurrent adapter.Outbound) error
lintOutbound = func(oTree []string, oCurrent adapter.Outbound) error {
problemOutboundTag := common.Find(oCurrent.Dependencies(), func(it string) bool {
return !started[it]
})
if common.Contains(oTree, problemOutboundTag) {
return E.New("circular outbound dependency: ", strings.Join(oTree, " -> "), " -> ", problemOutboundTag)
}
problemOutbound := outbounds[problemOutboundTag]
if problemOutbound == nil {
return E.New("dependency[", problemOutbound, "] not found for outbound[", outboundTags[oCurrent], "]")
}
return lintOutbound(append(oTree, problemOutboundTag), problemOutbound)
}
return lintOutbound([]string{outboundTags[currentOutbound]}, currentOutbound)
}
return nil
}

View File

@@ -1,6 +1,7 @@
package main package main
import ( import (
"go/build"
"os" "os"
"os/exec" "os/exec"
@@ -11,6 +12,10 @@ import (
func main() { func main() {
build_shared.FindSDK() build_shared.FindSDK()
if os.Getenv("build.Default.GOPATH") == "" {
os.Setenv("GOPATH", build.Default.GOPATH)
}
command := exec.Command(os.Args[1], os.Args[2:]...) command := exec.Command(os.Args[1], os.Args[2:]...)
command.Stdout = os.Stdout command.Stdout = os.Stdout
command.Stderr = os.Stderr command.Stderr = os.Stderr

View File

@@ -53,8 +53,7 @@ func init() {
sharedFlags = append(sharedFlags, "-X github.com/sagernet/sing-box/constant.Version="+currentTag+" -s -w -buildid=") sharedFlags = append(sharedFlags, "-X github.com/sagernet/sing-box/constant.Version="+currentTag+" -s -w -buildid=")
debugFlags = append(debugFlags, "-X github.com/sagernet/sing-box/constant.Version="+currentTag) debugFlags = append(debugFlags, "-X github.com/sagernet/sing-box/constant.Version="+currentTag)
sharedTags = append(sharedTags, "with_gvisor", "with_quic", "with_wireguard", "with_utls", "with_clash_api") sharedTags = append(sharedTags, "with_gvisor", "with_quic", "with_dhcp", "with_wireguard", "with_utls", "with_clash_api")
sharedTags = append(sharedTags, "test_sing_shadowsocks2")
debugTags = append(debugTags, "debug") debugTags = append(debugTags, "debug")
} }

View File

@@ -1,3 +1,17 @@
#### 1.3-beta14
* Fixes and improvements
#### 1.3-beta13
* Fix resolving fakeip domains **1**
* Deprecate L3 routing
* Fix bugs and update dependencies
**1**:
If the destination address of the connection is obtained from fakeip, dns rules with server type fakeip will be skipped.
#### 1.3-beta12 #### 1.3-beta12
* Automatically add Windows firewall rules in order for the system tun stack to work * Automatically add Windows firewall rules in order for the system tun stack to work

View File

@@ -7,7 +7,6 @@
"route": { "route": {
"geoip": {}, "geoip": {},
"geosite": {}, "geosite": {},
"ip_rules": [],
"rules": [], "rules": [],
"final": "", "final": "",
"auto_detect_interface": false, "auto_detect_interface": false,
@@ -24,7 +23,6 @@
|------------|------------------------------------| |------------|------------------------------------|
| `geoip` | [GeoIP](./geoip) | | `geoip` | [GeoIP](./geoip) |
| `geosite` | [Geosite](./geosite) | | `geosite` | [Geosite](./geosite) |
| `ip_rules` | List of [IP Route Rule](./ip-rule) |
| `rules` | List of [Route Rule](./rule) | | `rules` | List of [Route Rule](./rule) |
#### final #### final

View File

@@ -47,6 +47,7 @@
"inet4_range": "198.18.0.0/15", "inet4_range": "198.18.0.0/15",
"inet6_range": "fc00::/18" "inet6_range": "fc00::/18"
}, },
"independent_cache": true,
"strategy": "ipv4_only" "strategy": "ipv4_only"
}, },
"inbounds": [ "inbounds": [

View File

@@ -47,6 +47,7 @@
"inet4_range": "198.18.0.0/15", "inet4_range": "198.18.0.0/15",
"inet6_range": "fc00::/18" "inet6_range": "fc00::/18"
}, },
"independent_cache": true,
"strategy": "ipv4_only" "strategy": "ipv4_only"
}, },
"inbounds": [ "inbounds": [

View File

@@ -5,8 +5,7 @@ responds to DNS requests with virtual results and restores mapping when acceptin
#### Advantage #### Advantage
* Retrieve the requested domain in places like IP routing (L3) where traffic detection is not possible to assist with routing. *
* Decrease an RTT on the first TCP request to a domain (the most common reason).
#### Limitation #### Limitation
@@ -15,6 +14,6 @@ responds to DNS requests with virtual results and restores mapping when acceptin
#### Recommendation #### Recommendation
* Do not use if you do not need L3 routing. * Enable `dns.independent_cache` unless you always resolve FakeIP domains remotely.
* If using tun, make sure FakeIP ranges is included in the tun's routes. * If using tun, make sure FakeIP ranges is included in the tun's routes.
* Enable `experimental.clash_api.store_fakeip` to persist FakeIP records, or use `dns.rules.rewrite_ttl` to avoid losing records after program restart in DNS cached environments. * Enable `experimental.clash_api.store_fakeip` to persist FakeIP records, or use `dns.rules.rewrite_ttl` to avoid losing records after program restart in DNS cached environments.

View File

@@ -4,8 +4,7 @@ FakeIP 是指同时劫持 DNS 和连接请求的程序中的一种行为。它
#### 优点 #### 优点
* 在像 L3 路由这样无法进行流量探测的地方检索所请求的域名,以协助路由。 *
* 减少对一个域的第一个 TCP 请求的 RTT这是最常见的原因
#### 限制 #### 限制
@@ -14,6 +13,6 @@ FakeIP 是指同时劫持 DNS 和连接请求的程序中的一种行为。它
#### 建议 #### 建议
* 如果不需要 L3 路由,请勿使用 * 启用 `dns.independent_cache` 除非您始终远程解析 FakeIP 域
* 如果使用 tun请确保 tun 路由中包含 FakeIP 地址范围。 * 如果使用 tun请确保 tun 路由中包含 FakeIP 地址范围。
* 启用 `experimental.clash_api.store_fakeip` 以持久化 FakeIP 记录,或者使用 `dns.rules.rewrite_ttl` 避免程序重启后在 DNS 被缓存的环境中丢失记录。 * 启用 `experimental.clash_api.store_fakeip` 以持久化 FakeIP 记录,或者使用 `dns.rules.rewrite_ttl` 避免程序重启后在 DNS 被缓存的环境中丢失记录。

50
go.mod
View File

@@ -4,8 +4,8 @@ go 1.18
require ( require (
berty.tech/go-libtor v1.0.385 berty.tech/go-libtor v1.0.385
github.com/Dreamacro/clash v1.15.1 github.com/Dreamacro/clash v1.16.0
github.com/caddyserver/certmagic v0.17.2 github.com/caddyserver/certmagic v0.18.0
github.com/cretz/bine v0.2.0 github.com/cretz/bine v0.2.0
github.com/dustin/go-humanize v1.0.1 github.com/dustin/go-humanize v1.0.1
github.com/fsnotify/fsnotify v1.6.0 github.com/fsnotify/fsnotify v1.6.0
@@ -13,24 +13,25 @@ require (
github.com/go-chi/cors v1.2.1 github.com/go-chi/cors v1.2.1
github.com/go-chi/render v1.0.2 github.com/go-chi/render v1.0.2
github.com/gofrs/uuid/v5 v5.0.0 github.com/gofrs/uuid/v5 v5.0.0
github.com/insomniacslk/dhcp v0.0.0-20230407062729-974c6f05fe16 github.com/insomniacslk/dhcp v0.0.0-20230516061539-49801966e6cb
github.com/logrusorgru/aurora v2.0.3+incompatible github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/mholt/acmez v1.1.0 github.com/mholt/acmez v1.1.1
github.com/miekg/dns v1.1.54 github.com/miekg/dns v1.1.54
github.com/ooni/go-libtor v1.1.7 github.com/ooni/go-libtor v1.1.8
github.com/oschwald/maxminddb-golang v1.10.0 github.com/oschwald/maxminddb-golang v1.10.0
github.com/pires/go-proxyproto v0.7.0 github.com/pires/go-proxyproto v0.7.0
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0 github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0
github.com/sagernet/gomobile v0.0.0-20230413023804-244d7ff07035 github.com/sagernet/gomobile v0.0.0-20230413023804-244d7ff07035
github.com/sagernet/gvisor v0.0.0-20230611140528-4411f7659a08
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
github.com/sagernet/sing v0.2.5-0.20230517124404-be6013893626 github.com/sagernet/sing v0.2.5-0.20230613142554-a3b120b25eab
github.com/sagernet/sing-dns v0.1.5-0.20230426113254-25d948c44223 github.com/sagernet/sing-dns v0.1.5-0.20230426113254-25d948c44223
github.com/sagernet/sing-mux v0.0.0-20230517134606-1ebe6bb26646 github.com/sagernet/sing-mux v0.0.0-20230517134606-1ebe6bb26646
github.com/sagernet/sing-shadowsocks v0.2.2-0.20230509053848-d83f8fe1194c github.com/sagernet/sing-shadowsocks v0.2.2-0.20230509053848-d83f8fe1194c
github.com/sagernet/sing-shadowsocks2 v0.0.0-20230605050515-45409ce8283d github.com/sagernet/sing-shadowsocks2 v0.0.0-20230608022204-942fbd98f846
github.com/sagernet/sing-shadowtls v0.1.2-0.20230531025805-ebadc7615da3 github.com/sagernet/sing-shadowtls v0.1.2-0.20230531025805-ebadc7615da3
github.com/sagernet/sing-tun v0.1.5-0.20230520041100-b02f2529160e github.com/sagernet/sing-tun v0.1.5-0.20230611140633-41b2639e1385
github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3 github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37
github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9
@@ -38,23 +39,23 @@ require (
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e
github.com/sagernet/wireguard-go v0.0.0-20230420044414-a7bac1754e77 github.com/sagernet/wireguard-go v0.0.0-20230420044414-a7bac1754e77
github.com/spf13/cobra v1.7.0 github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.8.2 github.com/stretchr/testify v1.8.4
go.etcd.io/bbolt v1.3.7 go.etcd.io/bbolt v1.3.7
go.uber.org/zap v1.24.0 go.uber.org/zap v1.24.0
go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35
golang.org/x/crypto v0.8.0 golang.org/x/crypto v0.9.0
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
golang.org/x/net v0.9.0 golang.org/x/net v0.10.0
golang.org/x/sys v0.7.0 golang.org/x/sys v0.8.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.54.0 google.golang.org/grpc v1.55.0
google.golang.org/protobuf v1.30.0 google.golang.org/protobuf v1.30.0
gvisor.dev/gvisor v0.0.0-20230415003630-3981d5d5e523
) )
//replace github.com/sagernet/sing => ../sing //replace github.com/sagernet/sing => ../sing
require ( require (
github.com/Dreamacro/protobytes v0.0.0-20230324064118-87bc784139cd // indirect
github.com/ajg/form v1.5.1 // indirect github.com/ajg/form v1.5.1 // indirect
github.com/andybalholm/brotli v1.0.5 // indirect github.com/andybalholm/brotli v1.0.5 // indirect
github.com/cloudflare/circl v1.2.1-0.20221019164342-6ab4dfed8f3c // indirect github.com/cloudflare/circl v1.2.1-0.20221019164342-6ab4dfed8f3c // indirect
@@ -62,18 +63,19 @@ require (
github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/golang/mock v1.6.0 // indirect github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/google/btree v1.0.1 // indirect github.com/google/btree v1.1.2 // indirect
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/native v1.1.0 // indirect github.com/josharian/native v1.1.0 // indirect
github.com/klauspost/compress v1.15.15 // indirect github.com/klauspost/compress v1.15.15 // indirect
github.com/klauspost/cpuid/v2 v2.1.1 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/libdns/libdns v0.2.1 // indirect github.com/libdns/libdns v0.2.1 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/onsi/ginkgo/v2 v2.2.0 // indirect github.com/onsi/ginkgo/v2 v2.2.0 // indirect
github.com/pierrec/lz4/v4 v4.1.14 // indirect github.com/pierrec/lz4/v4 v4.1.14 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-18 v0.2.0 // indirect github.com/quic-go/qtls-go1-18 v0.2.0 // indirect
@@ -85,13 +87,13 @@ require (
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
go.uber.org/atomic v1.10.0 // indirect go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/mod v0.8.0 // indirect golang.org/x/mod v0.10.0 // indirect
golang.org/x/text v0.9.0 // indirect golang.org/x/text v0.9.0 // indirect
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.6.0 // indirect golang.org/x/tools v0.8.0 // indirect
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // 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
lukechampine.com/blake3 v1.1.7 // indirect lukechampine.com/blake3 v1.1.7 // indirect

108
go.sum
View File

@@ -1,14 +1,16 @@
berty.tech/go-libtor v1.0.385 h1:RWK94C3hZj6Z2GdvePpHJLnWYobFr3bY/OdUJ5aoEXw= berty.tech/go-libtor v1.0.385 h1:RWK94C3hZj6Z2GdvePpHJLnWYobFr3bY/OdUJ5aoEXw=
berty.tech/go-libtor v1.0.385/go.mod h1:9swOOQVb+kmvuAlsgWUK/4c52pm69AdbJsxLzk+fJEw= berty.tech/go-libtor v1.0.385/go.mod h1:9swOOQVb+kmvuAlsgWUK/4c52pm69AdbJsxLzk+fJEw=
github.com/Dreamacro/clash v1.15.1 h1:AwwtrVYbeXg9ZCxpPxAurGXwaR3FxDdHv3rB/vAGXj4= github.com/Dreamacro/clash v1.16.0 h1:Ve+8mvtsCv7ySa6f53/GOW6Tho0AFp5RNFsgQZFKcZs=
github.com/Dreamacro/clash v1.15.1/go.mod h1:WNH69bN11LiAdgdSr4hpkEuXVMfBbWyhEKMCTx9BtNE= github.com/Dreamacro/clash v1.16.0/go.mod h1:ZM3UI2gqqUN7UL7L/F9aTHODTByya6sbC/WivQpaoJk=
github.com/Dreamacro/protobytes v0.0.0-20230324064118-87bc784139cd h1:ygk7IF14j4ep4H2ZyeDe3IEoMZF8JdbX851RVVa/4D8=
github.com/Dreamacro/protobytes v0.0.0-20230324064118-87bc784139cd/go.mod h1:QvmEZ/h6KXszPOr2wUFl7Zn3hfFNYdfbXwPVDTyZs6k=
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= 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 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/caddyserver/certmagic v0.17.2 h1:o30seC1T/dBqBCNNGNHWwj2i5/I/FMjBbTAhjADP3nE= github.com/caddyserver/certmagic v0.18.0 h1:L22mJES1WllfLoHUcQUy4wVO7UfOsoL5wtg/Bj7kmIw=
github.com/caddyserver/certmagic v0.17.2/go.mod h1:ouWUuC490GOLJzkyN35eXfV8bSbwMwSf4bdhkIxtdQE= github.com/caddyserver/certmagic v0.18.0/go.mod h1:e0YLTnXIopZ05bBWCLzpIf1Yvk27Q90FGUmGowFRDY8=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@@ -40,10 +42,10 @@ github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
@@ -53,16 +55,16 @@ github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbg
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/insomniacslk/dhcp v0.0.0-20230407062729-974c6f05fe16 h1:+aAGyK41KRn8jbF2Q7PLL0Sxwg6dShGcQSeCC7nZQ8E= github.com/insomniacslk/dhcp v0.0.0-20230516061539-49801966e6cb h1:6fDKEAXwe3rsfS4khW3EZ8kEqmSiV9szhMPcDrD+Y7Q=
github.com/insomniacslk/dhcp v0.0.0-20230407062729-974c6f05fe16/go.mod h1:IKrnDWs3/Mqq5n0lI+RxA2sB7MvN/vbMBP3ehXg65UI= github.com/insomniacslk/dhcp v0.0.0-20230516061539-49801966e6cb/go.mod h1:7474bZ1YNCvarT6WFKie4kEET6J0KYRDC4XJqqXzQW4=
github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= 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= github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw=
github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.1.1 h1:t0wUqjowdm8ezddV5k0tLWVklVuvLJpoHeb4WBdydm0= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -70,8 +72,8 @@ github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40= github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/mholt/acmez v1.1.0 h1:IQ9CGHKOHokorxnffsqDvmmE30mDenO1lptYZ1AYkHY= github.com/mholt/acmez v1.1.1 h1:sYeeYd/EHVm9cSmLdWey5oW/fXFVAq5pNLjSczN2ZUg=
github.com/mholt/acmez v1.1.0/go.mod h1:zwo5+fbLLTowAX8o8ETfQzbDtwGEXnPhkmGdKIP+bgs= github.com/mholt/acmez v1.1.1/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI=
github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
@@ -79,8 +81,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI= github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
github.com/ooni/go-libtor v1.1.7 h1:ooVcdEPBqDox5OfeXAfXIeQFCbqMLJVfIpO+Irr7N9A= github.com/ooni/go-libtor v1.1.8 h1:Wo3V3DVTxl5vZdxtQakqYP+DAHx7pPtAFSl1bnAa08w=
github.com/ooni/go-libtor v1.1.7/go.mod h1:q1YyLwRD9GeMyeerVvwc0vJ2YgwDLTp2bdVcrh/JXyI= github.com/ooni/go-libtor v1.1.8/go.mod h1:q1YyLwRD9GeMyeerVvwc0vJ2YgwDLTp2bdVcrh/JXyI=
github.com/oschwald/maxminddb-golang v1.10.0 h1:Xp1u0ZhqkSuopaKmk1WwHtjF0H9Hd9181uj2MQ5Vndg= github.com/oschwald/maxminddb-golang v1.10.0 h1:Xp1u0ZhqkSuopaKmk1WwHtjF0H9Hd9181uj2MQ5Vndg=
github.com/oschwald/maxminddb-golang v1.10.0/go.mod h1:Y2ELenReaLAZ0b400URyGwvYxHV1dLIxBuyOsyYjHK0= github.com/oschwald/maxminddb-golang v1.10.0/go.mod h1:Y2ELenReaLAZ0b400URyGwvYxHV1dLIxBuyOsyYjHK0=
github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE= github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE=
@@ -88,6 +90,7 @@ github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFu
github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs= github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4= github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
@@ -105,6 +108,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/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms=
github.com/sagernet/gomobile v0.0.0-20230413023804-244d7ff07035 h1:KttYh6bBhIw8Y6/Ljn7CGwC3CKZn788rzMJmeAKjY+8= github.com/sagernet/gomobile v0.0.0-20230413023804-244d7ff07035 h1:KttYh6bBhIw8Y6/Ljn7CGwC3CKZn788rzMJmeAKjY+8=
github.com/sagernet/gomobile v0.0.0-20230413023804-244d7ff07035/go.mod h1:5YE39YkJkCcMsfq1jMKkjsrM2GfBoF9JVWnvU89hmvU= github.com/sagernet/gomobile v0.0.0-20230413023804-244d7ff07035/go.mod h1:5YE39YkJkCcMsfq1jMKkjsrM2GfBoF9JVWnvU89hmvU=
github.com/sagernet/gvisor v0.0.0-20230611140528-4411f7659a08 h1:p1z8y0tXLCKSiJ7GbUlaYPhyEbWL8LKLMYFpVxRVsBg=
github.com/sagernet/gvisor v0.0.0-20230611140528-4411f7659a08/go.mod h1:FgbjODax/nj7J2lr7+rqe88vHs0Ts93pC9na5ZiG9wg=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE= 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/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 h1:tztuJB+giOWNRKQEBVY2oI3PsheTooMdh+/yxemYQYY= github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 h1:tztuJB+giOWNRKQEBVY2oI3PsheTooMdh+/yxemYQYY=
@@ -113,20 +118,20 @@ 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/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.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.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
github.com/sagernet/sing v0.2.5-0.20230517124404-be6013893626 h1:2TlOqs05+PXadWOubVBhXM27/UaI1If2k/ISjtYZiPE= github.com/sagernet/sing v0.2.5-0.20230613142554-a3b120b25eab h1:9AVUIqqz/UJCgIrcJBU9mb06JXzfQ/FgEmlgdPgo2dk=
github.com/sagernet/sing v0.2.5-0.20230517124404-be6013893626/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= github.com/sagernet/sing v0.2.5-0.20230613142554-a3b120b25eab/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w=
github.com/sagernet/sing-dns v0.1.5-0.20230426113254-25d948c44223 h1:L4eMuM07iSHY3UCknFnuFuHoe5clZuF2Xnf2wwA6Lwc= github.com/sagernet/sing-dns v0.1.5-0.20230426113254-25d948c44223 h1:L4eMuM07iSHY3UCknFnuFuHoe5clZuF2Xnf2wwA6Lwc=
github.com/sagernet/sing-dns v0.1.5-0.20230426113254-25d948c44223/go.mod h1:ZKuuqgsHRxDahYrzgSgy4vIAGGuKPlIf4hLcNzYzLkY= github.com/sagernet/sing-dns v0.1.5-0.20230426113254-25d948c44223/go.mod h1:ZKuuqgsHRxDahYrzgSgy4vIAGGuKPlIf4hLcNzYzLkY=
github.com/sagernet/sing-mux v0.0.0-20230517134606-1ebe6bb26646 h1:X3ADfMqeGns1Q1FlXc9kaL9FwW1UM6D6tEQo8jFstpc= github.com/sagernet/sing-mux v0.0.0-20230517134606-1ebe6bb26646 h1:X3ADfMqeGns1Q1FlXc9kaL9FwW1UM6D6tEQo8jFstpc=
github.com/sagernet/sing-mux v0.0.0-20230517134606-1ebe6bb26646/go.mod h1:pF+RnLvCAOhECrvauy6LYOpBakJ/vuaF1Wm4lPsWryI= github.com/sagernet/sing-mux v0.0.0-20230517134606-1ebe6bb26646/go.mod h1:pF+RnLvCAOhECrvauy6LYOpBakJ/vuaF1Wm4lPsWryI=
github.com/sagernet/sing-shadowsocks v0.2.2-0.20230509053848-d83f8fe1194c h1:EiQ+i4gdPpSI8D2YUlOeBZA3R1ZGi0ShSLSXoSd/13A= github.com/sagernet/sing-shadowsocks v0.2.2-0.20230509053848-d83f8fe1194c h1:EiQ+i4gdPpSI8D2YUlOeBZA3R1ZGi0ShSLSXoSd/13A=
github.com/sagernet/sing-shadowsocks v0.2.2-0.20230509053848-d83f8fe1194c/go.mod h1:UJjvQGw0lyYaDGIDvUraL16fwaAEH1WFw1Y6sUcMPog= github.com/sagernet/sing-shadowsocks v0.2.2-0.20230509053848-d83f8fe1194c/go.mod h1:UJjvQGw0lyYaDGIDvUraL16fwaAEH1WFw1Y6sUcMPog=
github.com/sagernet/sing-shadowsocks2 v0.0.0-20230605050515-45409ce8283d h1:obf7pm6aRav465lIGPGN8fx8pD8iWg15RQhwGwkyNNc= github.com/sagernet/sing-shadowsocks2 v0.0.0-20230608022204-942fbd98f846 h1:aiEEbDyPS/IFx0V9RNa1yLdxHHegNP+q7JFpST/8D5I=
github.com/sagernet/sing-shadowsocks2 v0.0.0-20230605050515-45409ce8283d/go.mod h1:i6Eoor37Cy4JKBcelMMFfUVBNjqRYuvcqOBjUI3Zw80= github.com/sagernet/sing-shadowsocks2 v0.0.0-20230608022204-942fbd98f846/go.mod h1:i6Eoor37Cy4JKBcelMMFfUVBNjqRYuvcqOBjUI3Zw80=
github.com/sagernet/sing-shadowtls v0.1.2-0.20230531025805-ebadc7615da3 h1:PNwJs1F+3e/iZguYQR7YzxsH8Sm0Eu7vVuHawD89r34= github.com/sagernet/sing-shadowtls v0.1.2-0.20230531025805-ebadc7615da3 h1:PNwJs1F+3e/iZguYQR7YzxsH8Sm0Eu7vVuHawD89r34=
github.com/sagernet/sing-shadowtls v0.1.2-0.20230531025805-ebadc7615da3/go.mod h1:oG8bPerYI6cZ74KquY3DvA7ynECyrILPBnce6wtBqeI= github.com/sagernet/sing-shadowtls v0.1.2-0.20230531025805-ebadc7615da3/go.mod h1:oG8bPerYI6cZ74KquY3DvA7ynECyrILPBnce6wtBqeI=
github.com/sagernet/sing-tun v0.1.5-0.20230520041100-b02f2529160e h1:fivkzQowiOPBafklJmNePBu/sr83rsY5SuSakvoJ2A0= github.com/sagernet/sing-tun v0.1.5-0.20230611140633-41b2639e1385 h1:iKDIJB05yHyUE57VYlamGhCEauXssIukB/xZsLmP7ic=
github.com/sagernet/sing-tun v0.1.5-0.20230520041100-b02f2529160e/go.mod h1:6yju6cNdTow38IZHwcbFA3lHnHeSd5HG/zCzHyaxScI= github.com/sagernet/sing-tun v0.1.5-0.20230611140633-41b2639e1385/go.mod h1:8amChfsau8s/hkooIVIU4uw7VavgrfHrT0KUbJo4ROc=
github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3 h1:BHOnxrbC929JonuKqFdJ7ZbDp7zs4oTlH5KFvKtWu9U= github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3 h1:BHOnxrbC929JonuKqFdJ7ZbDp7zs4oTlH5KFvKtWu9U=
github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3/go.mod h1:yKrAr+dqZd64DxBXCHWrYicp+n4qbqO73mtwv3dck8U= github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3/go.mod h1:yKrAr+dqZd64DxBXCHWrYicp+n4qbqO73mtwv3dck8U=
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as= github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as=
@@ -146,15 +151,11 @@ github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRM
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=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 h1:tHNk7XK9GkmKUR6Gh8gVBKXc2MVSZ4G/NnWLtzw4gNA= github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 h1:tHNk7XK9GkmKUR6Gh8gVBKXc2MVSZ4G/NnWLtzw4gNA=
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264= github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg= github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
@@ -162,12 +163,11 @@ github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 h1:nJAwRlGWZZDOD+6wni9KVUNHMpHko/OnRwsrCYeAzPo= go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 h1:nJAwRlGWZZDOD+6wni9KVUNHMpHko/OnRwsrCYeAzPo=
@@ -176,23 +176,23 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
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.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
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.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -208,32 +208,32 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/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.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
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.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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-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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/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 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 v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA=
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
@@ -245,7 +245,5 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gvisor.dev/gvisor v0.0.0-20230415003630-3981d5d5e523 h1:zUQYeyyPLnSR6yMvLSOmLH37xDWCZ7BqlpE69fE5K3Q=
gvisor.dev/gvisor v0.0.0-20230415003630-3981d5d5e523/go.mod h1:pzr6sy8gDLfVmDAg8OYrlKvGEHw5C3PGTiBXBTCx76Q=
lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0=
lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA=

View File

@@ -19,10 +19,7 @@ import (
"github.com/sagernet/sing/common/ranges" "github.com/sagernet/sing/common/ranges"
) )
var ( var _ adapter.Inbound = (*Tun)(nil)
_ adapter.Inbound = (*Tun)(nil)
_ tun.Router = (*Tun)(nil)
)
type Tun struct { type Tun struct {
tag string tag string
@@ -161,10 +158,6 @@ func (t *Tun) Start() error {
} }
t.logger.Trace("creating stack") t.logger.Trace("creating stack")
t.tunIf = tunInterface t.tunIf = tunInterface
var tunRouter tun.Router
if len(t.router.IPRules()) > 0 {
tunRouter = t
}
t.tunStack, err = tun.NewStack(t.stack, tun.StackOptions{ t.tunStack, err = tun.NewStack(t.stack, tun.StackOptions{
Context: t.ctx, Context: t.ctx,
Tun: tunInterface, Tun: tunInterface,
@@ -174,7 +167,6 @@ func (t *Tun) Start() error {
Inet6Address: t.tunOptions.Inet6Address, Inet6Address: t.tunOptions.Inet6Address,
EndpointIndependentNat: t.endpointIndependentNat, EndpointIndependentNat: t.endpointIndependentNat,
UDPTimeout: t.udpTimeout, UDPTimeout: t.udpTimeout,
Router: tunRouter,
Handler: t, Handler: t,
Logger: t.logger, Logger: t.logger,
ForwarderBindInterface: t.platformInterface != nil, ForwarderBindInterface: t.platformInterface != nil,
@@ -199,21 +191,6 @@ func (t *Tun) Close() error {
) )
} }
func (t *Tun) RouteConnection(session tun.RouteSession, conn tun.RouteContext) tun.RouteAction {
ctx := log.ContextWithNewID(t.ctx)
var metadata adapter.InboundContext
metadata.Inbound = t.tag
metadata.InboundType = C.TypeTun
metadata.IPVersion = session.IPVersion
metadata.Network = tun.NetworkName(session.Network)
metadata.Source = M.SocksaddrFromNetIP(session.Source)
metadata.Destination = M.SocksaddrFromNetIP(session.Destination)
metadata.InboundOptions = t.inboundOptions
t.logger.DebugContext(ctx, "incoming connection from ", metadata.Source)
t.logger.DebugContext(ctx, "incoming connection to ", metadata.Destination)
return t.router.RouteIPConnection(ctx, conn, metadata)
}
func (t *Tun) NewConnection(ctx context.Context, conn net.Conn, upstreamMetadata M.Metadata) error { func (t *Tun) NewConnection(ctx context.Context, conn net.Conn, upstreamMetadata M.Metadata) error {
ctx = log.ContextWithNewID(ctx) ctx = log.ContextWithNewID(ctx)
var metadata adapter.InboundContext var metadata adapter.InboundContext

View File

@@ -55,7 +55,6 @@ nav:
- configuration/route/index.md - configuration/route/index.md
- GeoIP: configuration/route/geoip.md - GeoIP: configuration/route/geoip.md
- Geosite: configuration/route/geosite.md - Geosite: configuration/route/geosite.md
- IP Route Rule: configuration/route/ip-rule.md
- Route Rule: configuration/route/rule.md - Route Rule: configuration/route/rule.md
- Protocol Sniff: configuration/route/sniff.md - Protocol Sniff: configuration/route/sniff.md
- Experimental: - Experimental:
@@ -175,7 +174,6 @@ plugins:
DNS Rule: DNS 规则 DNS Rule: DNS 规则
Route: 路由 Route: 路由
IP Route Rule: IP 路由规则
Route Rule: 路由规则 Route Rule: 路由规则
Protocol Sniff: 协议探测 Protocol Sniff: 协议探测

View File

@@ -3,7 +3,6 @@ package option
type RouteOptions struct { type RouteOptions struct {
GeoIP *GeoIPOptions `json:"geoip,omitempty"` GeoIP *GeoIPOptions `json:"geoip,omitempty"`
Geosite *GeositeOptions `json:"geosite,omitempty"` Geosite *GeositeOptions `json:"geosite,omitempty"`
IPRules []IPRule `json:"ip_rules,omitempty"`
Rules []Rule `json:"rules,omitempty"` Rules []Rule `json:"rules,omitempty"`
Final string `json:"final,omitempty"` Final string `json:"final,omitempty"`
FindProcess bool `json:"find_process,omitempty"` FindProcess bool `json:"find_process,omitempty"`

View File

@@ -1,120 +0,0 @@
package option
import (
"reflect"
"github.com/sagernet/sing-box/common/json"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
type _IPRule struct {
Type string `json:"type,omitempty"`
DefaultOptions DefaultIPRule `json:"-"`
LogicalOptions LogicalIPRule `json:"-"`
}
type IPRule _IPRule
func (r IPRule) MarshalJSON() ([]byte, error) {
var v any
switch r.Type {
case C.RuleTypeDefault:
r.Type = ""
v = r.DefaultOptions
case C.RuleTypeLogical:
v = r.LogicalOptions
default:
return nil, E.New("unknown rule type: " + r.Type)
}
return MarshallObjects((_IPRule)(r), v)
}
func (r *IPRule) UnmarshalJSON(bytes []byte) error {
err := json.Unmarshal(bytes, (*_IPRule)(r))
if err != nil {
return err
}
var v any
switch r.Type {
case "", C.RuleTypeDefault:
r.Type = C.RuleTypeDefault
v = &r.DefaultOptions
case C.RuleTypeLogical:
v = &r.LogicalOptions
default:
return E.New("unknown rule type: " + r.Type)
}
err = UnmarshallExcluded(bytes, (*_IPRule)(r), v)
if err != nil {
return E.Cause(err, "ip route rule")
}
return nil
}
type DefaultIPRule struct {
Inbound Listable[string] `json:"inbound,omitempty"`
IPVersion int `json:"ip_version,omitempty"`
Network Listable[string] `json:"network,omitempty"`
Domain Listable[string] `json:"domain,omitempty"`
DomainSuffix Listable[string] `json:"domain_suffix,omitempty"`
DomainKeyword Listable[string] `json:"domain_keyword,omitempty"`
DomainRegex Listable[string] `json:"domain_regex,omitempty"`
Geosite Listable[string] `json:"geosite,omitempty"`
SourceGeoIP Listable[string] `json:"source_geoip,omitempty"`
GeoIP Listable[string] `json:"geoip,omitempty"`
SourceIPCIDR Listable[string] `json:"source_ip_cidr,omitempty"`
IPCIDR Listable[string] `json:"ip_cidr,omitempty"`
SourcePort Listable[uint16] `json:"source_port,omitempty"`
SourcePortRange Listable[string] `json:"source_port_range,omitempty"`
Port Listable[uint16] `json:"port,omitempty"`
PortRange Listable[string] `json:"port_range,omitempty"`
Invert bool `json:"invert,omitempty"`
Action RouteAction `json:"action,omitempty"`
Outbound string `json:"outbound,omitempty"`
}
type RouteAction tun.ActionType
func (a RouteAction) MarshalJSON() ([]byte, error) {
typeName, err := tun.ActionTypeName(tun.ActionType(a))
if err != nil {
return nil, err
}
return json.Marshal(typeName)
}
func (a *RouteAction) UnmarshalJSON(bytes []byte) error {
var value string
err := json.Unmarshal(bytes, &value)
if err != nil {
return err
}
actionType, err := tun.ParseActionType(value)
if err != nil {
return err
}
*a = RouteAction(actionType)
return nil
}
func (r DefaultIPRule) IsValid() bool {
var defaultValue DefaultIPRule
defaultValue.Invert = r.Invert
defaultValue.Outbound = r.Outbound
return !reflect.DeepEqual(r, defaultValue)
}
type LogicalIPRule struct {
Mode string `json:"mode"`
Rules []DefaultIPRule `json:"rules,omitempty"`
Invert bool `json:"invert,omitempty"`
Action RouteAction `json:"action,omitempty"`
Outbound string `json:"outbound,omitempty"`
}
func (r LogicalIPRule) IsValid() bool {
return len(r.Rules) > 0 && common.All(r.Rules, DefaultIPRule.IsValid)
}

View File

@@ -14,7 +14,6 @@ type WireGuardOutboundOptions struct {
Workers int `json:"workers,omitempty"` Workers int `json:"workers,omitempty"`
MTU uint32 `json:"mtu,omitempty"` MTU uint32 `json:"mtu,omitempty"`
Network NetworkList `json:"network,omitempty"` Network NetworkList `json:"network,omitempty"`
IPRewrite bool `json:"ip_rewrite,omitempty"`
} }
type WireGuardPeer struct { type WireGuardPeer struct {

View File

@@ -11,6 +11,7 @@ import (
"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/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/buf" "github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio" "github.com/sagernet/sing/common/bufio"
@@ -20,11 +21,12 @@ import (
) )
type myOutboundAdapter struct { type myOutboundAdapter struct {
protocol string protocol string
network []string network []string
router adapter.Router router adapter.Router
logger log.ContextLogger logger log.ContextLogger
tag string tag string
dependencies []string
} }
func (a *myOutboundAdapter) Type() string { func (a *myOutboundAdapter) Type() string {
@@ -39,10 +41,21 @@ func (a *myOutboundAdapter) Network() []string {
return a.network return a.network
} }
func (a *myOutboundAdapter) Dependencies() []string {
return a.dependencies
}
func (a *myOutboundAdapter) NewError(ctx context.Context, err error) { func (a *myOutboundAdapter) NewError(ctx context.Context, err error) {
NewError(a.logger, ctx, err) NewError(a.logger, ctx, err)
} }
func withDialerDependency(options option.DialerOptions) []string {
if options.Detour != "" {
return []string{options.Detour}
}
return nil
}
func NewConnection(ctx context.Context, this N.Dialer, conn net.Conn, metadata adapter.InboundContext) error { func NewConnection(ctx context.Context, this N.Dialer, conn net.Conn, metadata adapter.InboundContext) error {
ctx = adapter.WithContext(ctx, &metadata) ctx = adapter.WithContext(ctx, &metadata)
var outConn net.Conn var outConn net.Conn

View File

@@ -40,11 +40,12 @@ func NewDirect(router adapter.Router, logger log.ContextLogger, tag string, opti
options.UDPFragmentDefault = true options.UDPFragmentDefault = true
outbound := &Direct{ outbound := &Direct{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeDirect, protocol: C.TypeDirect,
network: []string{N.NetworkTCP, N.NetworkUDP}, network: []string{N.NetworkTCP, N.NetworkUDP},
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
domainStrategy: dns.DomainStrategy(options.DomainStrategy), domainStrategy: dns.DomainStrategy(options.DomainStrategy),
fallbackDelay: time.Duration(options.FallbackDelay), fallbackDelay: time.Duration(options.FallbackDelay),

View File

@@ -39,11 +39,12 @@ func NewHTTP(router adapter.Router, logger log.ContextLogger, tag string, option
} }
return &HTTP{ return &HTTP{
myOutboundAdapter{ myOutboundAdapter{
protocol: C.TypeHTTP, protocol: C.TypeHTTP,
network: []string{N.NetworkTCP}, network: []string{N.NetworkTCP},
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
sHTTP.NewClient(sHTTP.Options{ sHTTP.NewClient(sHTTP.Options{
Dialer: detour, Dialer: detour,

View File

@@ -119,11 +119,12 @@ func NewHysteria(ctx context.Context, router adapter.Router, logger log.ContextL
} }
return &Hysteria{ return &Hysteria{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeHysteria, protocol: C.TypeHysteria,
network: options.Network.Build(), network: options.Network.Build(),
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
ctx: ctx, ctx: ctx,
dialer: dialer.New(router, options.DialerOptions), dialer: dialer.New(router, options.DialerOptions),
@@ -150,6 +151,7 @@ func (h *Hysteria) offer(ctx context.Context) (quic.Connection, error) {
if conn != nil && !common.Done(conn.Context()) { if conn != nil && !common.Done(conn.Context()) {
return conn, nil return conn, nil
} }
common.Close(h.rawConn)
conn, err := h.offerNew(ctx) conn, err := h.offerNew(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -260,13 +262,19 @@ func (h *Hysteria) Close() error {
return nil return nil
} }
func (h *Hysteria) open(ctx context.Context) (quic.Connection, quic.Stream, error) { func (h *Hysteria) open(ctx context.Context, reconnect bool) (quic.Connection, quic.Stream, error) {
conn, err := h.offer(ctx) conn, err := h.offer(ctx)
if err != nil { if err != nil {
if nErr, ok := err.(net.Error); ok && !nErr.Temporary() && reconnect {
return h.open(ctx, false)
}
return nil, nil, err return nil, nil, err
} }
stream, err := conn.OpenStream() stream, err := conn.OpenStream()
if err != nil { if err != nil {
if nErr, ok := err.(net.Error); ok && !nErr.Temporary() && reconnect {
return h.open(ctx, false)
}
return nil, nil, err return nil, nil, err
} }
return conn, &hysteria.StreamWrapper{Stream: stream}, nil return conn, &hysteria.StreamWrapper{Stream: stream}, nil
@@ -276,7 +284,7 @@ func (h *Hysteria) DialContext(ctx context.Context, network string, destination
switch N.NetworkName(network) { switch N.NetworkName(network) {
case N.NetworkTCP: case N.NetworkTCP:
h.logger.InfoContext(ctx, "outbound connection to ", destination) h.logger.InfoContext(ctx, "outbound connection to ", destination)
_, stream, err := h.open(ctx) _, stream, err := h.open(ctx, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -302,7 +310,7 @@ func (h *Hysteria) DialContext(ctx context.Context, network string, destination
func (h *Hysteria) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { func (h *Hysteria) 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)
conn, stream, err := h.open(ctx) conn, stream, err := h.open(ctx, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -29,10 +29,11 @@ type Selector struct {
func NewSelector(router adapter.Router, logger log.ContextLogger, tag string, options option.SelectorOutboundOptions) (*Selector, error) { func NewSelector(router adapter.Router, logger log.ContextLogger, tag string, options option.SelectorOutboundOptions) (*Selector, error) {
outbound := &Selector{ outbound := &Selector{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeSelector, protocol: C.TypeSelector,
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: options.Outbounds,
}, },
tags: options.Outbounds, tags: options.Outbounds,
defaultTag: options.Default, defaultTag: options.Default,

View File

@@ -41,11 +41,12 @@ func NewShadowsocks(ctx context.Context, router adapter.Router, logger log.Conte
} }
outbound := &Shadowsocks{ outbound := &Shadowsocks{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeShadowsocks, protocol: C.TypeShadowsocks,
network: options.Network.Build(), network: options.Network.Build(),
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
dialer: dialer.New(router, options.DialerOptions), dialer: dialer.New(router, options.DialerOptions),
method: method, method: method,

View File

@@ -39,11 +39,12 @@ type ShadowsocksR struct {
func NewShadowsocksR(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksROutboundOptions) (*ShadowsocksR, error) { func NewShadowsocksR(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksROutboundOptions) (*ShadowsocksR, error) {
outbound := &ShadowsocksR{ outbound := &ShadowsocksR{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeShadowsocksR, protocol: C.TypeShadowsocksR,
network: options.Network.Build(), network: options.Network.Build(),
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
dialer: dialer.New(router, options.DialerOptions), dialer: dialer.New(router, options.DialerOptions),
serverAddr: options.ServerOptions.Build(), serverAddr: options.ServerOptions.Build(),

View File

@@ -27,11 +27,12 @@ type ShadowTLS struct {
func NewShadowTLS(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowTLSOutboundOptions) (*ShadowTLS, error) { func NewShadowTLS(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowTLSOutboundOptions) (*ShadowTLS, error) {
outbound := &ShadowTLS{ outbound := &ShadowTLS{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeShadowTLS, protocol: C.TypeShadowTLS,
network: []string{N.NetworkTCP}, network: []string{N.NetworkTCP},
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
} }
if options.TLS == nil || !options.TLS.Enabled { if options.TLS == nil || !options.TLS.Enabled {

View File

@@ -39,11 +39,12 @@ func NewSocks(router adapter.Router, logger log.ContextLogger, tag string, optio
} }
outbound := &Socks{ outbound := &Socks{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeSocks, protocol: C.TypeSocks,
network: options.Network.Build(), network: options.Network.Build(),
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
client: socks.NewClient(dialer.New(router, options.DialerOptions), options.ServerOptions.Build(), version, options.Username, options.Password), client: socks.NewClient(dialer.New(router, options.DialerOptions), options.ServerOptions.Build(), version, options.Username, options.Password),
resolve: version == socks.Version4, resolve: version == socks.Version4,

View File

@@ -46,11 +46,12 @@ type SSH struct {
func NewSSH(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.SSHOutboundOptions) (*SSH, error) { func NewSSH(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.SSHOutboundOptions) (*SSH, error) {
outbound := &SSH{ outbound := &SSH{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeSSH, protocol: C.TypeSSH,
network: []string{N.NetworkTCP}, network: []string{N.NetworkTCP},
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
ctx: ctx, ctx: ctx,
dialer: dialer.New(router, options.DialerOptions), dialer: dialer.New(router, options.DialerOptions),

View File

@@ -68,11 +68,12 @@ func NewTor(ctx context.Context, router adapter.Router, logger log.ContextLogger
} }
return &Tor{ return &Tor{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeTor, protocol: C.TypeTor,
network: []string{N.NetworkTCP}, network: []string{N.NetworkTCP},
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
ctx: ctx, ctx: ctx,
proxy: NewProxyListener(ctx, logger, dialer.New(router, options.DialerOptions)), proxy: NewProxyListener(ctx, logger, dialer.New(router, options.DialerOptions)),

View File

@@ -35,11 +35,12 @@ type Trojan struct {
func NewTrojan(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TrojanOutboundOptions) (*Trojan, error) { func NewTrojan(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TrojanOutboundOptions) (*Trojan, error) {
outbound := &Trojan{ outbound := &Trojan{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeTrojan, protocol: C.TypeTrojan,
network: options.Network.Build(), network: options.Network.Build(),
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
dialer: dialer.New(router, options.DialerOptions), dialer: dialer.New(router, options.DialerOptions),
serverAddr: options.ServerOptions.Build(), serverAddr: options.ServerOptions.Build(),

View File

@@ -39,10 +39,11 @@ type URLTest struct {
func NewURLTest(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.URLTestOutboundOptions) (*URLTest, error) { func NewURLTest(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.URLTestOutboundOptions) (*URLTest, error) {
outbound := &URLTest{ outbound := &URLTest{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeURLTest, protocol: C.TypeURLTest,
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: options.Outbounds,
}, },
ctx: ctx, ctx: ctx,
tags: options.Outbounds, tags: options.Outbounds,

View File

@@ -38,11 +38,12 @@ type VLESS struct {
func NewVLESS(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.VLESSOutboundOptions) (*VLESS, error) { func NewVLESS(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.VLESSOutboundOptions) (*VLESS, error) {
outbound := &VLESS{ outbound := &VLESS{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeVLESS, protocol: C.TypeVLESS,
network: options.Network.Build(), network: options.Network.Build(),
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
dialer: dialer.New(router, options.DialerOptions), dialer: dialer.New(router, options.DialerOptions),
serverAddr: options.ServerOptions.Build(), serverAddr: options.ServerOptions.Build(),

View File

@@ -37,11 +37,12 @@ type VMess struct {
func NewVMess(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.VMessOutboundOptions) (*VMess, error) { func NewVMess(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.VMessOutboundOptions) (*VMess, error) {
outbound := &VMess{ outbound := &VMess{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeVMess, protocol: C.TypeVMess,
network: options.Network.Build(), network: options.Network.Build(),
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
dialer: dialer.New(router, options.DialerOptions), dialer: dialer.New(router, options.DialerOptions),
serverAddr: options.ServerOptions.Build(), serverAddr: options.ServerOptions.Build(),

View File

@@ -8,9 +8,7 @@ import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"net" "net"
"os"
"strings" "strings"
"syscall"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/dialer" "github.com/sagernet/sing-box/common/dialer"
@@ -28,7 +26,7 @@ import (
) )
var ( var (
_ adapter.IPOutbound = (*WireGuard)(nil) _ adapter.Outbound = (*WireGuard)(nil)
_ adapter.InterfaceUpdateListener = (*WireGuard)(nil) _ adapter.InterfaceUpdateListener = (*WireGuard)(nil)
) )
@@ -36,18 +34,18 @@ type WireGuard struct {
myOutboundAdapter myOutboundAdapter
bind *wireguard.ClientBind bind *wireguard.ClientBind
device *device.Device device *device.Device
natDevice wireguard.NatDevice
tunDevice wireguard.Device tunDevice wireguard.Device
} }
func NewWireGuard(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.WireGuardOutboundOptions) (*WireGuard, error) { func NewWireGuard(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.WireGuardOutboundOptions) (*WireGuard, error) {
outbound := &WireGuard{ outbound := &WireGuard{
myOutboundAdapter: myOutboundAdapter{ myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeWireGuard, protocol: C.TypeWireGuard,
network: options.Network.Build(), network: options.Network.Build(),
router: router, router: router,
logger: logger, logger: logger,
tag: tag, tag: tag,
dependencies: withDialerDependency(options.DialerOptions),
}, },
} }
var reserved [3]uint8 var reserved [3]uint8
@@ -158,25 +156,17 @@ func NewWireGuard(ctx context.Context, router adapter.Router, logger log.Context
if mtu == 0 { if mtu == 0 {
mtu = 1408 mtu = 1408
} }
var tunDevice wireguard.Device var wireTunDevice wireguard.Device
var err error var err error
if !options.SystemInterface && tun.WithGVisor { if !options.SystemInterface && tun.WithGVisor {
tunDevice, err = wireguard.NewStackDevice(localPrefixes, mtu, options.IPRewrite) wireTunDevice, err = wireguard.NewStackDevice(localPrefixes, mtu)
} else { } else {
tunDevice, err = wireguard.NewSystemDevice(router, options.InterfaceName, localPrefixes, mtu) wireTunDevice, err = wireguard.NewSystemDevice(router, options.InterfaceName, localPrefixes, mtu)
} }
if err != nil { if err != nil {
return nil, E.Cause(err, "create WireGuard device") return nil, E.Cause(err, "create WireGuard device")
} }
natDevice, isNatDevice := tunDevice.(wireguard.NatDevice) wgDevice := device.NewDevice(wireTunDevice, outbound.bind, &device.Logger{
if !isNatDevice && router.NatRequired(tag) {
natDevice = wireguard.NewNATDevice(tunDevice, options.IPRewrite)
}
deviceInput := tunDevice
if natDevice != nil {
deviceInput = natDevice
}
wgDevice := device.NewDevice(deviceInput, outbound.bind, &device.Logger{
Verbosef: func(format string, args ...interface{}) { Verbosef: func(format string, args ...interface{}) {
logger.Debug(fmt.Sprintf(strings.ToLower(format), args...)) logger.Debug(fmt.Sprintf(strings.ToLower(format), args...))
}, },
@@ -192,8 +182,7 @@ func NewWireGuard(ctx context.Context, router adapter.Router, logger log.Context
return nil, E.Cause(err, "setup wireguard") return nil, E.Cause(err, "setup wireguard")
} }
outbound.device = wgDevice outbound.device = wgDevice
outbound.natDevice = natDevice outbound.tunDevice = wireTunDevice
outbound.tunDevice = tunDevice
return outbound, nil return outbound, nil
} }
@@ -232,27 +221,6 @@ func (w *WireGuard) NewPacketConnection(ctx context.Context, conn N.PacketConn,
return NewPacketConnection(ctx, w, conn, metadata) return NewPacketConnection(ctx, w, conn, metadata)
} }
func (w *WireGuard) NewIPConnection(ctx context.Context, conn tun.RouteContext, metadata adapter.InboundContext) (tun.DirectDestination, error) {
if w.natDevice == nil {
return nil, os.ErrInvalid
}
session := tun.RouteSession{
IPVersion: metadata.IPVersion,
Network: tun.NetworkFromName(metadata.Network),
Source: metadata.Source.AddrPort(),
Destination: metadata.Destination.AddrPort(),
}
switch session.Network {
case syscall.IPPROTO_TCP:
w.logger.InfoContext(ctx, "linked connection to ", metadata.Destination)
case syscall.IPPROTO_UDP:
w.logger.InfoContext(ctx, "linked packet connection to ", metadata.Destination)
default:
w.logger.InfoContext(ctx, "linked ", metadata.Network, " connection to ", metadata.Destination.AddrString())
}
return w.natDevice.CreateDestination(session, conn), nil
}
func (w *WireGuard) Start() error { func (w *WireGuard) Start() error {
return w.tunDevice.Start() return w.tunDevice.Start()
} }

View File

@@ -50,7 +50,6 @@ type Router struct {
outbounds []adapter.Outbound outbounds []adapter.Outbound
outboundByTag map[string]adapter.Outbound outboundByTag map[string]adapter.Outbound
rules []adapter.Rule rules []adapter.Rule
ipRules []adapter.IPRule
defaultDetour string defaultDetour string
defaultOutboundForConnection adapter.Outbound defaultOutboundForConnection adapter.Outbound
defaultOutboundForPacketConnection adapter.Outbound defaultOutboundForPacketConnection adapter.Outbound
@@ -99,7 +98,6 @@ func NewRouter(
dnsLogger: logFactory.NewLogger("dns"), dnsLogger: logFactory.NewLogger("dns"),
outboundByTag: make(map[string]adapter.Outbound), outboundByTag: make(map[string]adapter.Outbound),
rules: make([]adapter.Rule, 0, len(options.Rules)), rules: make([]adapter.Rule, 0, len(options.Rules)),
ipRules: make([]adapter.IPRule, 0, len(options.IPRules)),
dnsRules: make([]adapter.DNSRule, 0, len(dnsOptions.Rules)), dnsRules: make([]adapter.DNSRule, 0, len(dnsOptions.Rules)),
needGeoIPDatabase: hasRule(options.Rules, isGeoIPRule) || hasDNSRule(dnsOptions.Rules, isGeoIPDNSRule), needGeoIPDatabase: hasRule(options.Rules, isGeoIPRule) || hasDNSRule(dnsOptions.Rules, isGeoIPDNSRule),
needGeositeDatabase: hasRule(options.Rules, isGeositeRule) || hasDNSRule(dnsOptions.Rules, isGeositeDNSRule), needGeositeDatabase: hasRule(options.Rules, isGeositeRule) || hasDNSRule(dnsOptions.Rules, isGeositeDNSRule),
@@ -126,13 +124,6 @@ func NewRouter(
} }
router.rules = append(router.rules, routeRule) router.rules = append(router.rules, routeRule)
} }
for i, ipRuleOptions := range options.IPRules {
ipRule, err := NewIPRule(router, router.logger, ipRuleOptions)
if err != nil {
return nil, E.Cause(err, "parse ip rule[", i, "]")
}
router.ipRules = append(router.ipRules, ipRule)
}
for i, dnsRuleOptions := range dnsOptions.Rules { for i, dnsRuleOptions := range dnsOptions.Rules {
dnsRule, err := NewDNSRule(router, router.logger, dnsRuleOptions) dnsRule, err := NewDNSRule(router, router.logger, dnsRuleOptions)
if err != nil { if err != nil {
@@ -638,6 +629,7 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
Fqdn: domain, Fqdn: domain,
Port: metadata.Destination.Port, Port: metadata.Destination.Port,
} }
metadata.FakeIP = true
r.logger.DebugContext(ctx, "found fakeip domain: ", domain) r.logger.DebugContext(ctx, "found fakeip domain: ", domain)
} }
@@ -747,6 +739,7 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
Fqdn: domain, Fqdn: domain,
Port: metadata.Destination.Port, Port: metadata.Destination.Port,
} }
metadata.FakeIP = true
r.logger.DebugContext(ctx, "found fakeip domain: ", domain) r.logger.DebugContext(ctx, "found fakeip domain: ", domain)
} }
@@ -929,10 +922,6 @@ func (r *Router) Rules() []adapter.Rule {
return r.rules return r.rules
} }
func (r *Router) IPRules() []adapter.IPRule {
return r.ipRules
}
func (r *Router) NetworkMonitor() tun.NetworkUpdateMonitor { func (r *Router) NetworkMonitor() tun.NetworkUpdateMonitor {
return r.networkMonitor return r.networkMonitor
} }

View File

@@ -44,22 +44,27 @@ func (r *Router) matchDNS(ctx context.Context) (context.Context, dns.Transport,
} }
for i, rule := range r.dnsRules { for i, rule := range r.dnsRules {
if rule.Match(metadata) { if rule.Match(metadata) {
detour := rule.Outbound()
transport, loaded := r.transportMap[detour]
if !loaded {
r.dnsLogger.ErrorContext(ctx, "transport not found: ", detour)
continue
}
if _, isFakeIP := transport.(adapter.FakeIPTransport); isFakeIP && metadata.FakeIP {
continue
}
r.dnsLogger.DebugContext(ctx, "match[", i, "] ", rule.String(), " => ", detour)
if rule.DisableCache() { if rule.DisableCache() {
ctx = dns.ContextWithDisableCache(ctx, true) ctx = dns.ContextWithDisableCache(ctx, true)
} }
if rewriteTTL := rule.RewriteTTL(); rewriteTTL != nil { if rewriteTTL := rule.RewriteTTL(); rewriteTTL != nil {
ctx = dns.ContextWithRewriteTTL(ctx, *rewriteTTL) ctx = dns.ContextWithRewriteTTL(ctx, *rewriteTTL)
} }
detour := rule.Outbound() if domainStrategy, dsLoaded := r.transportDomainStrategy[transport]; dsLoaded {
r.dnsLogger.DebugContext(ctx, "match[", i, "] ", rule.String(), " => ", detour) return ctx, transport, domainStrategy
if transport, loaded := r.transportMap[detour]; loaded { } else {
if domainStrategy, dsLoaded := r.transportDomainStrategy[transport]; dsLoaded { return ctx, transport, r.defaultDomainStrategy
return ctx, transport, domainStrategy
} else {
return ctx, transport, r.defaultDomainStrategy
}
} }
r.dnsLogger.ErrorContext(ctx, "transport not found: ", detour)
} }
} }
if domainStrategy, dsLoaded := r.transportDomainStrategy[r.defaultTransport]; dsLoaded { if domainStrategy, dsLoaded := r.transportDomainStrategy[r.defaultTransport]; dsLoaded {

View File

@@ -1,79 +0,0 @@
package route
import (
"context"
"strings"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-dns"
"github.com/sagernet/sing-tun"
F "github.com/sagernet/sing/common/format"
M "github.com/sagernet/sing/common/metadata"
)
func (r *Router) RouteIPConnection(ctx context.Context, conn tun.RouteContext, metadata adapter.InboundContext) tun.RouteAction {
if r.fakeIPStore != nil && r.fakeIPStore.Contains(metadata.Destination.Addr) {
domain, loaded := r.fakeIPStore.Lookup(metadata.Destination.Addr)
if !loaded {
r.logger.ErrorContext(ctx, "missing fakeip context")
return (*tun.ActionReturn)(nil)
}
metadata.Destination = M.Socksaddr{
Fqdn: domain,
Port: metadata.Destination.Port,
}
r.logger.DebugContext(ctx, "found fakeip domain: ", domain)
}
if r.dnsReverseMapping != nil && metadata.Domain == "" {
domain, loaded := r.dnsReverseMapping.Query(metadata.Destination.Addr)
if loaded {
metadata.Domain = domain
r.logger.DebugContext(ctx, "found reserve mapped domain: ", metadata.Domain)
}
}
if metadata.Destination.IsFqdn() && dns.DomainStrategy(metadata.InboundOptions.DomainStrategy) != dns.DomainStrategyAsIS {
addresses, err := r.Lookup(adapter.WithContext(ctx, &metadata), metadata.Destination.Fqdn, dns.DomainStrategy(metadata.InboundOptions.DomainStrategy))
if err != nil {
r.logger.ErrorContext(ctx, err)
return (*tun.ActionReturn)(nil)
}
metadata.DestinationAddresses = addresses
r.dnsLogger.DebugContext(ctx, "resolved [", strings.Join(F.MapToString(metadata.DestinationAddresses), " "), "]")
}
for i, rule := range r.ipRules {
if rule.Match(&metadata) {
if rule.Action() == tun.ActionTypeBlock {
r.logger.InfoContext(ctx, "match[", i, "] ", rule.String(), " => block")
return (*tun.ActionBlock)(nil)
}
detour := rule.Outbound()
r.logger.InfoContext(ctx, "match[", i, "] ", rule.String(), " => ", detour)
outbound, loaded := r.Outbound(detour)
if !loaded {
r.logger.ErrorContext(ctx, "outbound not found: ", detour)
break
}
ipOutbound, loaded := outbound.(adapter.IPOutbound)
if !loaded {
r.logger.ErrorContext(ctx, "outbound have no ip connection support: ", detour)
break
}
destination, err := ipOutbound.NewIPConnection(ctx, conn, metadata)
if err != nil {
r.logger.ErrorContext(ctx, err)
break
}
return &tun.ActionDirect{DirectDestination: destination}
}
}
return (*tun.ActionReturn)(nil)
}
func (r *Router) NatRequired(outbound string) bool {
for _, ipRule := range r.ipRules {
if ipRule.Outbound() == outbound {
return true
}
}
return false
}

View File

@@ -1,189 +0,0 @@
package route
import (
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
)
func NewIPRule(router adapter.Router, logger log.ContextLogger, options option.IPRule) (adapter.IPRule, error) {
switch options.Type {
case "", C.RuleTypeDefault:
if !options.DefaultOptions.IsValid() {
return nil, E.New("missing conditions")
}
if common.IsEmpty(options.DefaultOptions.Action) {
return nil, E.New("missing action")
}
return NewDefaultIPRule(router, logger, options.DefaultOptions)
case C.RuleTypeLogical:
if !options.LogicalOptions.IsValid() {
return nil, E.New("missing conditions")
}
if common.IsEmpty(options.DefaultOptions.Action) {
return nil, E.New("missing action")
}
return NewLogicalIPRule(router, logger, options.LogicalOptions)
default:
return nil, E.New("unknown rule type: ", options.Type)
}
}
var _ adapter.IPRule = (*DefaultIPRule)(nil)
type DefaultIPRule struct {
abstractDefaultRule
action tun.ActionType
}
func NewDefaultIPRule(router adapter.Router, logger log.ContextLogger, options option.DefaultIPRule) (*DefaultIPRule, error) {
rule := &DefaultIPRule{
abstractDefaultRule: abstractDefaultRule{
invert: options.Invert,
outbound: options.Outbound,
},
action: tun.ActionType(options.Action),
}
if len(options.Inbound) > 0 {
item := NewInboundRule(options.Inbound)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
if options.IPVersion > 0 {
switch options.IPVersion {
case 4, 6:
item := NewIPVersionItem(options.IPVersion == 6)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
default:
return nil, E.New("invalid ip version: ", options.IPVersion)
}
}
if len(options.Network) > 0 {
item := NewNetworkItem(options.Network)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.Domain) > 0 || len(options.DomainSuffix) > 0 {
item := NewDomainItem(options.Domain, options.DomainSuffix)
rule.destinationAddressItems = append(rule.destinationAddressItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.DomainKeyword) > 0 {
item := NewDomainKeywordItem(options.DomainKeyword)
rule.destinationAddressItems = append(rule.destinationAddressItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.DomainRegex) > 0 {
item, err := NewDomainRegexItem(options.DomainRegex)
if err != nil {
return nil, E.Cause(err, "domain_regex")
}
rule.destinationAddressItems = append(rule.destinationAddressItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.Geosite) > 0 {
item := NewGeositeItem(router, logger, options.Geosite)
rule.destinationAddressItems = append(rule.destinationAddressItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.SourceGeoIP) > 0 {
item := NewGeoIPItem(router, logger, true, options.SourceGeoIP)
rule.sourceAddressItems = append(rule.sourceAddressItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.GeoIP) > 0 {
item := NewGeoIPItem(router, logger, false, options.GeoIP)
rule.destinationAddressItems = append(rule.destinationAddressItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.SourceIPCIDR) > 0 {
item, err := NewIPCIDRItem(true, options.SourceIPCIDR)
if err != nil {
return nil, E.Cause(err, "source_ipcidr")
}
rule.sourceAddressItems = append(rule.sourceAddressItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.IPCIDR) > 0 {
item, err := NewIPCIDRItem(false, options.IPCIDR)
if err != nil {
return nil, E.Cause(err, "ipcidr")
}
rule.destinationAddressItems = append(rule.destinationAddressItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.SourcePort) > 0 {
item := NewPortItem(true, options.SourcePort)
rule.sourcePortItems = append(rule.sourcePortItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.SourcePortRange) > 0 {
item, err := NewPortRangeItem(true, options.SourcePortRange)
if err != nil {
return nil, E.Cause(err, "source_port_range")
}
rule.sourcePortItems = append(rule.sourcePortItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.Port) > 0 {
item := NewPortItem(false, options.Port)
rule.destinationPortItems = append(rule.destinationPortItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.PortRange) > 0 {
item, err := NewPortRangeItem(false, options.PortRange)
if err != nil {
return nil, E.Cause(err, "port_range")
}
rule.destinationPortItems = append(rule.destinationPortItems, item)
rule.allItems = append(rule.allItems, item)
}
return rule, nil
}
func (r *DefaultIPRule) Action() tun.ActionType {
return r.action
}
var _ adapter.IPRule = (*LogicalIPRule)(nil)
type LogicalIPRule struct {
abstractLogicalRule
action tun.ActionType
}
func NewLogicalIPRule(router adapter.Router, logger log.ContextLogger, options option.LogicalIPRule) (*LogicalIPRule, error) {
r := &LogicalIPRule{
abstractLogicalRule: abstractLogicalRule{
rules: make([]adapter.Rule, len(options.Rules)),
invert: options.Invert,
outbound: options.Outbound,
},
action: tun.ActionType(options.Action),
}
switch options.Mode {
case C.LogicalTypeAnd:
r.mode = C.LogicalTypeAnd
case C.LogicalTypeOr:
r.mode = C.LogicalTypeOr
default:
return nil, E.New("unknown logical mode: ", options.Mode)
}
for i, subRule := range options.Rules {
rule, err := NewDefaultIPRule(router, logger, subRule)
if err != nil {
return nil, E.Cause(err, "sub rule[", i, "]")
}
r.rules[i] = rule
}
return r, nil
}
func (r *LogicalIPRule) Action() tun.ActionType {
return r.action
}

View File

@@ -10,7 +10,7 @@ require (
github.com/docker/docker v20.10.18+incompatible github.com/docker/docker v20.10.18+incompatible
github.com/docker/go-connections v0.4.0 github.com/docker/go-connections v0.4.0
github.com/gofrs/uuid/v5 v5.0.0 github.com/gofrs/uuid/v5 v5.0.0
github.com/sagernet/sing v0.2.5-0.20230423085534-0902e6216207 github.com/sagernet/sing v0.2.4
github.com/sagernet/sing-shadowsocks v0.2.2-0.20230417102954-f77257340507 github.com/sagernet/sing-shadowsocks v0.2.2-0.20230417102954-f77257340507
github.com/spyzhov/ajson v0.7.1 github.com/spyzhov/ajson v0.7.1
github.com/stretchr/testify v1.8.2 github.com/stretchr/testify v1.8.2
@@ -71,7 +71,6 @@ require (
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 // indirect github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 // indirect
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect
github.com/sagernet/sing-dns v0.1.5-0.20230415085626-111ecf799dfc // indirect github.com/sagernet/sing-dns v0.1.5-0.20230415085626-111ecf799dfc // indirect
github.com/sagernet/sing-mux v0.0.0-20230424015424-9b0d527c3bb0 // indirect
github.com/sagernet/sing-shadowtls v0.1.2-0.20230417103049-4f682e05f19b // indirect github.com/sagernet/sing-shadowtls v0.1.2-0.20230417103049-4f682e05f19b // indirect
github.com/sagernet/sing-tun v0.1.5-0.20230422121432-209ec123ca7b // indirect github.com/sagernet/sing-tun v0.1.5-0.20230422121432-209ec123ca7b // indirect
github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3 // indirect github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3 // indirect

View File

@@ -126,12 +126,10 @@ 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/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.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.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
github.com/sagernet/sing v0.2.5-0.20230423085534-0902e6216207 h1:+dDVjW20IT+e8maKryaDeRY2+RFmTFdrQeIzqE2WOss= github.com/sagernet/sing v0.2.4 h1:gC8BR5sglbJZX23RtMyFa8EETP9YEUADhfbEzU1yVbo=
github.com/sagernet/sing v0.2.5-0.20230423085534-0902e6216207/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= github.com/sagernet/sing v0.2.4/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w=
github.com/sagernet/sing-dns v0.1.5-0.20230415085626-111ecf799dfc h1:hmbuqKv48SAjiKPoqtJGvS5pEHVPZjTHq9CPwQY2cZ4= github.com/sagernet/sing-dns v0.1.5-0.20230415085626-111ecf799dfc h1:hmbuqKv48SAjiKPoqtJGvS5pEHVPZjTHq9CPwQY2cZ4=
github.com/sagernet/sing-dns v0.1.5-0.20230415085626-111ecf799dfc/go.mod h1:ZKuuqgsHRxDahYrzgSgy4vIAGGuKPlIf4hLcNzYzLkY= github.com/sagernet/sing-dns v0.1.5-0.20230415085626-111ecf799dfc/go.mod h1:ZKuuqgsHRxDahYrzgSgy4vIAGGuKPlIf4hLcNzYzLkY=
github.com/sagernet/sing-mux v0.0.0-20230424015424-9b0d527c3bb0 h1:87jyxzTjq01VgEiUVSMNRKjCfsSfp/QwyUVT37eXY50=
github.com/sagernet/sing-mux v0.0.0-20230424015424-9b0d527c3bb0/go.mod h1:pF+RnLvCAOhECrvauy6LYOpBakJ/vuaF1Wm4lPsWryI=
github.com/sagernet/sing-shadowsocks v0.2.2-0.20230417102954-f77257340507 h1:bAHZCdWqJkb8LEW98+YsMVDXGRMUVjka8IC+St6ot88= github.com/sagernet/sing-shadowsocks v0.2.2-0.20230417102954-f77257340507 h1:bAHZCdWqJkb8LEW98+YsMVDXGRMUVjka8IC+St6ot88=
github.com/sagernet/sing-shadowsocks v0.2.2-0.20230417102954-f77257340507/go.mod h1:UJjvQGw0lyYaDGIDvUraL16fwaAEH1WFw1Y6sUcMPog= github.com/sagernet/sing-shadowsocks v0.2.2-0.20230417102954-f77257340507/go.mod h1:UJjvQGw0lyYaDGIDvUraL16fwaAEH1WFw1Y6sUcMPog=
github.com/sagernet/sing-shadowtls v0.1.2-0.20230417103049-4f682e05f19b h1:ouW/6IDCrxkBe19YSbdCd7buHix7b+UZ6BM4Zz74XF4= github.com/sagernet/sing-shadowtls v0.1.2-0.20230417103049-4f682e05f19b h1:ouW/6IDCrxkBe19YSbdCd7buHix7b+UZ6BM4Zz74XF4=

View File

@@ -4,6 +4,7 @@ import (
"net/netip" "net/netip"
"testing" "testing"
"github.com/sagernet/sing-box/common/mux"
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-shadowsocks/shadowaead_2022" "github.com/sagernet/sing-shadowsocks/shadowaead_2022"
@@ -11,32 +12,45 @@ import (
"github.com/gofrs/uuid/v5" "github.com/gofrs/uuid/v5"
) )
var muxProtocols = []string{ var muxProtocols = []mux.Protocol{
"smux", mux.ProtocolYAMux,
"yamux", mux.ProtocolSMux,
"h2mux",
} }
func TestMux(t *testing.T) { func TestVMessSMux(t *testing.T) {
testVMessMux(t, option.MultiplexOptions{
Enabled: true,
Protocol: mux.ProtocolSMux.String(),
})
}
func TestShadowsocksMux(t *testing.T) {
for _, protocol := range muxProtocols { for _, protocol := range muxProtocols {
t.Run(protocol, func(t *testing.T) { t.Run(protocol.String(), func(t *testing.T) {
options := option.MultiplexOptions{ testShadowsocksMux(t, option.MultiplexOptions{
Enabled: true, Enabled: true,
Protocol: protocol, Protocol: protocol.String(),
}
t.Run("shadowsocks", func(t *testing.T) {
testShadowsocksMux(t, options)
})
t.Run("vmess", func(t *testing.T) {
testVMessMux(t, options)
})
t.Run("vless", func(t *testing.T) {
testVLESSMux(t, options)
}) })
}) })
} }
} }
func TestShadowsockH2Mux(t *testing.T) {
testShadowsocksMux(t, option.MultiplexOptions{
Enabled: true,
Protocol: mux.ProtocolH2Mux.String(),
Padding: true,
})
}
func TestShadowsockSMuxPadding(t *testing.T) {
testShadowsocksMux(t, option.MultiplexOptions{
Enabled: true,
Protocol: mux.ProtocolSMux.String(),
Padding: true,
})
}
func testShadowsocksMux(t *testing.T, options option.MultiplexOptions) { func testShadowsocksMux(t *testing.T, options option.MultiplexOptions) {
method := shadowaead_2022.List[0] method := shadowaead_2022.List[0]
password := mkBase64(t, 16) password := mkBase64(t, 16)
@@ -156,63 +170,3 @@ func testVMessMux(t *testing.T, options option.MultiplexOptions) {
}) })
testSuit(t, clientPort, testPort) testSuit(t, clientPort, testPort)
} }
func testVLESSMux(t *testing.T, options option.MultiplexOptions) {
user, _ := uuid.NewV4()
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.TypeVLESS,
VLESSOptions: option.VLESSInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
ListenPort: serverPort,
},
Users: []option.VLESSUser{
{
UUID: user.String(),
},
},
},
},
},
Outbounds: []option.Outbound{
{
Type: C.TypeDirect,
},
{
Type: C.TypeVLESS,
Tag: "vless-out",
VLESSOptions: option.VLESSOutboundOptions{
ServerOptions: option.ServerOptions{
Server: "127.0.0.1",
ServerPort: serverPort,
},
UUID: user.String(),
Multiplex: &options,
},
},
},
Route: &option.RouteOptions{
Rules: []option.Rule{
{
DefaultOptions: option.DefaultRule{
Inbound: []string{"mixed-in"},
Outbound: "vless-out",
},
},
},
},
})
testSuit(t, clientPort, testPort)
}

View File

@@ -14,13 +14,16 @@ import (
mDNS "github.com/miekg/dns" mDNS "github.com/miekg/dns"
) )
var _ dns.Transport = (*Server)(nil) var (
_ dns.Transport = (*Transport)(nil)
_ adapter.FakeIPTransport = (*Transport)(nil)
)
func init() { func init() {
dns.RegisterTransport([]string{"fakeip"}, NewTransport) dns.RegisterTransport([]string{"fakeip"}, NewTransport)
} }
type Server struct { type Transport struct {
name string name string
router adapter.Router router adapter.Router
store adapter.FakeIPStore store adapter.FakeIPStore
@@ -32,18 +35,18 @@ func NewTransport(name string, ctx context.Context, logger logger.ContextLogger,
if router == nil { if router == nil {
return nil, E.New("missing router in context") return nil, E.New("missing router in context")
} }
return &Server{ return &Transport{
name: name, name: name,
router: router, router: router,
logger: logger, logger: logger,
}, nil }, nil
} }
func (s *Server) Name() string { func (s *Transport) Name() string {
return s.name return s.name
} }
func (s *Server) Start() error { func (s *Transport) Start() error {
s.store = s.router.FakeIPStore() s.store = s.router.FakeIPStore()
if s.store == nil { if s.store == nil {
return E.New("fakeip not enabled") return E.New("fakeip not enabled")
@@ -51,19 +54,19 @@ func (s *Server) Start() error {
return nil return nil
} }
func (s *Server) Close() error { func (s *Transport) Close() error {
return nil return nil
} }
func (s *Server) Raw() bool { func (s *Transport) Raw() bool {
return false return false
} }
func (s *Server) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) { func (s *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
return nil, os.ErrInvalid return nil, os.ErrInvalid
} }
func (s *Server) Lookup(ctx context.Context, domain string, strategy dns.DomainStrategy) ([]netip.Addr, error) { func (s *Transport) Lookup(ctx context.Context, domain string, strategy dns.DomainStrategy) ([]netip.Addr, error) {
var addresses []netip.Addr var addresses []netip.Addr
if strategy != dns.DomainStrategyUseIPv6 { if strategy != dns.DomainStrategyUseIPv6 {
inet4Address, err := s.store.Create(domain, dns.DomainStrategyUseIPv4) inet4Address, err := s.store.Create(domain, dns.DomainStrategyUseIPv4)
@@ -81,3 +84,7 @@ func (s *Server) Lookup(ctx context.Context, domain string, strategy dns.DomainS
} }
return addresses, nil return addresses, nil
} }
func (s *Transport) Store() adapter.FakeIPStore {
return s.store
}

View File

@@ -1,23 +1,13 @@
package wireguard package wireguard
import ( import (
"net/netip"
"github.com/sagernet/sing-tun"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
wgTun "github.com/sagernet/wireguard-go/tun" "github.com/sagernet/wireguard-go/tun"
) )
type Device interface { type Device interface {
wgTun.Device tun.Device
N.Dialer N.Dialer
Start() error Start() error
Inet4Address() netip.Addr
Inet6Address() netip.Addr
// NewEndpoint() (stack.LinkEndpoint, error) // NewEndpoint() (stack.LinkEndpoint, error)
} }
type NatDevice interface {
Device
CreateDestination(session tun.RouteSession, conn tun.RouteContext) tun.DirectDestination
}

View File

@@ -1,76 +0,0 @@
package wireguard
import (
"github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common/buf"
)
var _ Device = (*natDeviceWrapper)(nil)
type natDeviceWrapper struct {
Device
outbound chan *buf.Buffer
mapping *tun.NatMapping
writer *tun.NatWriter
}
func NewNATDevice(upstream Device, ipRewrite bool) NatDevice {
wrapper := &natDeviceWrapper{
Device: upstream,
outbound: make(chan *buf.Buffer, 256),
mapping: tun.NewNatMapping(ipRewrite),
}
if ipRewrite {
wrapper.writer = tun.NewNatWriter(upstream.Inet4Address(), upstream.Inet6Address())
}
return wrapper
}
func (d *natDeviceWrapper) Read(bufs [][]byte, sizes []int, offset int) (count int, err error) {
select {
case packet := <-d.outbound:
defer packet.Release()
sizes[0] = copy(bufs[0][offset:], packet.Bytes())
return 1, nil
default:
}
return d.Device.Read(bufs, sizes, offset)
}
func (d *natDeviceWrapper) Write(bufs [][]byte, offset int) (count int, err error) {
packet := bufs[0][offset:]
handled, err := d.mapping.WritePacket(packet)
if handled {
return 1, err
}
return d.Device.Write(bufs, offset)
}
func (d *natDeviceWrapper) CreateDestination(session tun.RouteSession, conn tun.RouteContext) tun.DirectDestination {
d.mapping.CreateSession(session, conn)
return &natDestinationWrapper{d, session}
}
var _ tun.DirectDestination = (*natDestinationWrapper)(nil)
type natDestinationWrapper struct {
device *natDeviceWrapper
session tun.RouteSession
}
func (d *natDestinationWrapper) WritePacket(buffer *buf.Buffer) error {
if d.device.writer != nil {
d.device.writer.RewritePacket(buffer.Bytes())
}
d.device.outbound <- buffer
return nil
}
func (d *natDestinationWrapper) Close() error {
d.device.mapping.DeleteSession(d.session)
return nil
}
func (d *natDestinationWrapper) Timeout() bool {
return false
}

View File

@@ -1,27 +0,0 @@
//go:build with_gvisor
package wireguard
import (
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/buf"
"gvisor.dev/gvisor/pkg/tcpip/stack"
)
func (d *natDestinationWrapper) WritePacketBuffer(buffer stack.PacketBufferPtr) error {
defer buffer.DecRef()
if d.device.writer != nil {
d.device.writer.RewritePacketBuffer(buffer)
}
var packetLen int
for _, slice := range buffer.AsSlices() {
packetLen += len(slice)
}
packet := buf.NewSize(packetLen)
for _, slice := range buffer.AsSlices() {
common.Must1(packet.Write(slice))
}
d.device.outbound <- packet
return nil
}

View File

@@ -8,26 +8,25 @@ import (
"net/netip" "net/netip"
"os" "os"
"github.com/sagernet/gvisor/pkg/buffer"
"github.com/sagernet/gvisor/pkg/tcpip"
"github.com/sagernet/gvisor/pkg/tcpip/adapters/gonet"
"github.com/sagernet/gvisor/pkg/tcpip/header"
"github.com/sagernet/gvisor/pkg/tcpip/network/ipv4"
"github.com/sagernet/gvisor/pkg/tcpip/network/ipv6"
"github.com/sagernet/gvisor/pkg/tcpip/stack"
"github.com/sagernet/gvisor/pkg/tcpip/transport/icmp"
"github.com/sagernet/gvisor/pkg/tcpip/transport/tcp"
"github.com/sagernet/gvisor/pkg/tcpip/transport/udp"
"github.com/sagernet/sing-tun" "github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common/buf" "github.com/sagernet/sing/common/buf"
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"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
wgTun "github.com/sagernet/wireguard-go/tun" wgTun "github.com/sagernet/wireguard-go/tun"
"gvisor.dev/gvisor/pkg/bufferv2"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
"gvisor.dev/gvisor/pkg/tcpip/header"
"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
"gvisor.dev/gvisor/pkg/tcpip/stack"
"gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
) )
var _ NatDevice = (*StackDevice)(nil) var _ Device = (*StackDevice)(nil)
const defaultNIC tcpip.NICID = 1 const defaultNIC tcpip.NICID = 1
@@ -41,11 +40,9 @@ type StackDevice struct {
dispatcher stack.NetworkDispatcher dispatcher stack.NetworkDispatcher
addr4 tcpip.Address addr4 tcpip.Address
addr6 tcpip.Address addr6 tcpip.Address
mapping *tun.NatMapping
writer *tun.NatWriter
} }
func NewStackDevice(localAddresses []netip.Prefix, mtu uint32, ipRewrite bool) (*StackDevice, error) { func NewStackDevice(localAddresses []netip.Prefix, mtu uint32) (*StackDevice, error) {
ipStack := stack.New(stack.Options{ ipStack := stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol}, NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol, icmp.NewProtocol4, icmp.NewProtocol6}, TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol, icmp.NewProtocol4, icmp.NewProtocol6},
@@ -58,14 +55,13 @@ func NewStackDevice(localAddresses []netip.Prefix, mtu uint32, ipRewrite bool) (
outbound: make(chan stack.PacketBufferPtr, 256), outbound: make(chan stack.PacketBufferPtr, 256),
packetOutbound: make(chan *buf.Buffer, 256), packetOutbound: make(chan *buf.Buffer, 256),
done: make(chan struct{}), done: make(chan struct{}),
mapping: tun.NewNatMapping(ipRewrite),
} }
err := ipStack.CreateNIC(defaultNIC, (*wireEndpoint)(tunDevice)) err := ipStack.CreateNIC(defaultNIC, (*wireEndpoint)(tunDevice))
if err != nil { if err != nil {
return nil, E.New(err.String()) return nil, E.New(err.String())
} }
for _, prefix := range localAddresses { for _, prefix := range localAddresses {
addr := tcpip.Address(prefix.Addr().AsSlice()) addr := tun.AddressFromAddr(prefix.Addr())
protoAddr := tcpip.ProtocolAddress{ protoAddr := tcpip.ProtocolAddress{
AddressWithPrefix: tcpip.AddressWithPrefix{ AddressWithPrefix: tcpip.AddressWithPrefix{
Address: addr, Address: addr,
@@ -84,9 +80,6 @@ func NewStackDevice(localAddresses []netip.Prefix, mtu uint32, ipRewrite bool) (
return nil, E.New("parse local address ", protoAddr.AddressWithPrefix, ": ", err.String()) return nil, E.New("parse local address ", protoAddr.AddressWithPrefix, ": ", err.String())
} }
} }
if ipRewrite {
tunDevice.writer = tun.NewNatWriter(tunDevice.Inet4Address(), tunDevice.Inet6Address())
}
sOpt := tcpip.TCPSACKEnabled(true) sOpt := tcpip.TCPSACKEnabled(true)
ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &sOpt) ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &sOpt)
cOpt := tcpip.CongestionControlOption("cubic") cOpt := tcpip.CongestionControlOption("cubic")
@@ -104,7 +97,7 @@ func (w *StackDevice) DialContext(ctx context.Context, network string, destinati
addr := tcpip.FullAddress{ addr := tcpip.FullAddress{
NIC: defaultNIC, NIC: defaultNIC,
Port: destination.Port, Port: destination.Port,
Addr: tcpip.Address(destination.Addr.AsSlice()), Addr: tun.AddressFromAddr(destination.Addr),
} }
bind := tcpip.FullAddress{ bind := tcpip.FullAddress{
NIC: defaultNIC, NIC: defaultNIC,
@@ -140,7 +133,7 @@ func (w *StackDevice) ListenPacket(ctx context.Context, destination M.Socksaddr)
NIC: defaultNIC, NIC: defaultNIC,
} }
var networkProtocol tcpip.NetworkProtocolNumber var networkProtocol tcpip.NetworkProtocolNumber
if destination.IsIPv4() || w.addr6 == "" { if destination.IsIPv4() {
networkProtocol = header.IPv4ProtocolNumber networkProtocol = header.IPv4ProtocolNumber
bind.Addr = w.addr4 bind.Addr = w.addr4
} else { } else {
@@ -155,11 +148,11 @@ func (w *StackDevice) ListenPacket(ctx context.Context, destination M.Socksaddr)
} }
func (w *StackDevice) Inet4Address() netip.Addr { func (w *StackDevice) Inet4Address() netip.Addr {
return M.AddrFromIP(net.IP(w.addr4)) return tun.AddrFromAddress(w.addr4)
} }
func (w *StackDevice) Inet6Address() netip.Addr { func (w *StackDevice) Inet6Address() netip.Addr {
return M.AddrFromIP(net.IP(w.addr6)) return tun.AddrFromAddress(w.addr6)
} }
func (w *StackDevice) Start() error { func (w *StackDevice) Start() error {
@@ -203,14 +196,6 @@ func (w *StackDevice) Write(bufs [][]byte, offset int) (count int, err error) {
if len(b) == 0 { if len(b) == 0 {
continue continue
} }
handled, err := w.mapping.WritePacket(b)
if handled {
count++
if err != nil {
return count, err
}
continue
}
var networkProtocol tcpip.NetworkProtocolNumber var networkProtocol tcpip.NetworkProtocolNumber
switch header.IPVersion(b) { switch header.IPVersion(b) {
case header.IPv4Version: case header.IPv4Version:
@@ -219,7 +204,7 @@ func (w *StackDevice) Write(bufs [][]byte, offset int) (count int, err error) {
networkProtocol = header.IPv6ProtocolNumber networkProtocol = header.IPv6ProtocolNumber
} }
packetBuffer := stack.NewPacketBuffer(stack.PacketBufferOptions{ packetBuffer := stack.NewPacketBuffer(stack.PacketBufferOptions{
Payload: bufferv2.MakeWithData(b), Payload: buffer.MakeWithData(b),
}) })
w.dispatcher.DeliverNetworkPacket(networkProtocol, packetBuffer) w.dispatcher.DeliverNetworkPacket(networkProtocol, packetBuffer)
packetBuffer.DecRef() packetBuffer.DecRef()
@@ -263,44 +248,6 @@ func (w *StackDevice) BatchSize() int {
return 1 return 1
} }
func (w *StackDevice) CreateDestination(session tun.RouteSession, conn tun.RouteContext) tun.DirectDestination {
w.mapping.CreateSession(session, conn)
return &stackNatDestination{
device: w,
session: session,
}
}
type stackNatDestination struct {
device *StackDevice
session tun.RouteSession
}
func (d *stackNatDestination) WritePacket(buffer *buf.Buffer) error {
if d.device.writer != nil {
d.device.writer.RewritePacket(buffer.Bytes())
}
d.device.packetOutbound <- buffer
return nil
}
func (d *stackNatDestination) WritePacketBuffer(buffer stack.PacketBufferPtr) error {
if d.device.writer != nil {
d.device.writer.RewritePacketBuffer(buffer)
}
d.device.outbound <- buffer
return nil
}
func (d *stackNatDestination) Close() error {
d.device.mapping.DeleteSession(d.session)
return nil
}
func (d *stackNatDestination) Timeout() bool {
return false
}
var _ stack.LinkEndpoint = (*wireEndpoint)(nil) var _ stack.LinkEndpoint = (*wireEndpoint)(nil)
type wireEndpoint StackDevice type wireEndpoint StackDevice

View File

@@ -8,6 +8,6 @@ import (
"github.com/sagernet/sing-tun" "github.com/sagernet/sing-tun"
) )
func NewStackDevice(localAddresses []netip.Prefix, mtu uint32, ipRewrite bool) (Device, error) { func NewStackDevice(localAddresses []netip.Prefix, mtu uint32) (Device, error) {
return nil, tun.ErrGVisorNotIncluded return nil, tun.ErrGVisorNotIncluded
} }

View File

@@ -7,15 +7,16 @@ import (
"errors" "errors"
"fmt" "fmt"
"net" "net"
"net/netip"
"time" "time"
"github.com/sagernet/gvisor/pkg/tcpip"
"github.com/sagernet/gvisor/pkg/tcpip/adapters/gonet"
"github.com/sagernet/gvisor/pkg/tcpip/stack"
"github.com/sagernet/gvisor/pkg/tcpip/transport/tcp"
"github.com/sagernet/gvisor/pkg/waiter"
"github.com/sagernet/sing-tun"
M "github.com/sagernet/sing/common/metadata" M "github.com/sagernet/sing/common/metadata"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
"gvisor.dev/gvisor/pkg/tcpip/stack"
"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
"gvisor.dev/gvisor/pkg/waiter"
) )
func DialTCPWithBind(ctx context.Context, s *stack.Stack, localAddr, remoteAddr tcpip.FullAddress, network tcpip.NetworkProtocolNumber) (*gonet.TCPConn, error) { func DialTCPWithBind(ctx context.Context, s *stack.Stack, localAddr, remoteAddr tcpip.FullAddress, network tcpip.NetworkProtocolNumber) (*gonet.TCPConn, error) {
@@ -62,7 +63,7 @@ func DialTCPWithBind(ctx context.Context, s *stack.Stack, localAddr, remoteAddr
return nil, &net.OpError{ return nil, &net.OpError{
Op: "connect", Op: "connect",
Net: "tcp", Net: "tcp",
Addr: M.SocksaddrFrom(M.AddrFromIP(net.IP(remoteAddr.Addr)), remoteAddr.Port).TCPAddr(), Addr: M.SocksaddrFromNetIP(netip.AddrPortFrom(tun.AddrFromAddress(remoteAddr.Addr), remoteAddr.Port)).TCPAddr(),
Err: errors.New(err.String()), Err: errors.New(err.String()),
} }
} }