Compare commits

...

53 Commits

Author SHA1 Message Date
世界
ffe515d0e0 documentation: Update changelog 2023-07-25 13:21:15 +08:00
世界
aad021f521 Fix gVisor UDP 2023-07-25 08:28:24 +08:00
世界
4a986459ee documentation: Update changelog 2023-07-24 17:56:39 +08:00
世界
9532d0cba4 Fix cache file 2023-07-24 16:51:03 +08:00
世界
cadc34f3ad Add support for macOS system extension 2023-07-24 16:51:03 +08:00
世界
db23a48b36 Update dependencies 2023-07-23 14:23:51 +08:00
世界
407cf68e59 Fix certmagic usage 2023-07-20 20:03:20 +08:00
世界
e0058ca9c5 Fix fakeip unsaved state 2023-07-20 19:59:04 +08:00
世界
8140af01aa Fix download geo resources 2023-07-20 19:41:22 +08:00
世界
98bf696d01 Fix cache file 2023-07-20 19:41:22 +08:00
世界
e075bb5c8d Update changelog 2023-07-19 14:59:30 +08:00
世界
c6baabedef Update dependencies 2023-07-19 14:45:30 +08:00
世界
6e6998dab7 Improve platform status 2023-07-16 14:08:45 +08:00
世界
1a29c23263 documentation: Update changelog 2023-07-15 14:53:48 +08:00
世界
0f87396ab6 Fix abx reader for some malformed formats 2023-07-15 14:46:15 +08:00
世界
ffde948860 Update support page 2023-07-15 14:46:09 +08:00
世界
69b5dbdcc3 Build memory limiter for android 2023-07-15 14:46:06 +08:00
世界
1121517755 Fix hysteria inbound context 2023-07-11 20:58:20 +08:00
世界
6879def619 Fix test 2023-07-11 15:44:03 +08:00
世界
5c0f6d0a6f Fix vmess legacy server 2023-07-11 15:44:03 +08:00
世界
d74abbd20e Fix v2ray websocket transport 2023-07-11 15:44:03 +08:00
世界
120dae4eed Fix fakeip lookup 2023-07-11 15:44:02 +08:00
世界
bb651db2d2 platform: Fix output format 2023-07-09 12:24:43 +08:00
世界
e929dde13e documentation: Update changelog 2023-07-09 07:54:08 +08:00
世界
9d75385bbb Fix async FakeIP save 2023-07-08 16:21:11 +08:00
世界
1c526feec1 Update dependencies 2023-07-08 16:19:28 +08:00
世界
7df26986de documentation: Update changelog 2023-07-07 14:23:45 +08:00
世界
5f2d23a12d Fix multi error 2023-07-07 13:57:28 +08:00
世界
d9e65c0969 Fix syscall copy packet 2023-07-07 13:42:42 +08:00
世界
ec1160924f Fix save FakeIP cache 2023-07-07 12:51:38 +08:00
世界
230e8f895d Fix close quic.Listener 2023-07-07 12:43:22 +08:00
世界
af79378734 Update dependencies 2023-07-03 21:47:32 +08:00
世界
07ce5e0d22 Remove stack buffer usage 2023-07-03 21:45:32 +08:00
世界
9c8565cf21 platform: Add group interface 2023-07-02 18:46:41 +08:00
世界
5ad0ea2b5a Try fix StreamDomainNameQuery 2023-07-02 16:38:38 +08:00
世界
e482053c8a documentation: Update changelog 2023-06-27 11:31:24 +08:00
世界
945713d886 Update dependencies 2023-06-27 11:13:30 +08:00
世界
9bb62ad6b5 Check duplicated outbound tag 2023-06-26 18:47:52 +08:00
世界
c2bda9fbde Fix DNS rewrite_ttl logic 2023-06-23 16:12:25 +08:00
世界
1d1db62a44 Prevent write packet IPv6 packet to tun IPv4 connection 2023-06-21 13:29:24 +08:00
世界
39405373f8 documentation: Update changelog 2023-06-19 14:11:41 +08:00
世界
22a7988d3f Update dependencies 2023-06-19 14:11:41 +08:00
世界
b2092fafb7 Fix ios build
Cannot use errno as method and variable due to conflict with objc
2023-06-19 14:11:40 +08:00
世界
cc7b5d8280 Unwrap 4in6 address received by client packet conn 2023-06-19 13:29:41 +08:00
世界
702d96a738 platform: Improve local DNS transport 2023-06-18 10:00:32 +08:00
世界
b9f34f1309 documentation: Update changelog 2023-06-17 12:21:18 +08:00
世界
07724a0ddd Update dependencies 2023-06-17 12:17:43 +08:00
世界
83c3454685 Update quic-go 2023-06-15 14:52:25 +08:00
世界
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
106 changed files with 1781 additions and 993 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
@@ -89,8 +89,8 @@ lib:
lib_install: lib_install:
go get -v -d go get -v -d
go install -v github.com/sagernet/gomobile/cmd/gomobile@v0.0.0-20230413023804-244d7ff07035 go install -v github.com/sagernet/gomobile/cmd/gomobile@v0.0.0-20230701084532-493ee2e45182
go install -v github.com/sagernet/gomobile/cmd/gobind@v0.0.0-20230413023804-244d7ff07035 go install -v github.com/sagernet/gomobile/cmd/gobind@v0.0.0-20230701084532-493ee2e45182
clean: clean:
rm -rf bin dist sing-box rm -rf bin dist sing-box

View File

@@ -31,6 +31,7 @@ type Tracker interface {
} }
type OutboundGroup interface { type OutboundGroup interface {
Outbound
Now() string Now() string
All() []string All() []string
} }

View File

@@ -4,12 +4,13 @@ import (
"net/netip" "net/netip"
"github.com/sagernet/sing-dns" "github.com/sagernet/sing-dns"
"github.com/sagernet/sing/common/logger"
) )
type FakeIPStore interface { type FakeIPStore interface {
Service Service
Contains(address netip.Addr) bool Contains(address netip.Addr) bool
Create(domain string, strategy dns.DomainStrategy) (netip.Addr, error) Create(domain string, isIPv6 bool) (netip.Addr, error)
Lookup(address netip.Addr) (string, bool) Lookup(address netip.Addr) (string, bool)
Reset() error Reset() error
} }
@@ -18,7 +19,9 @@ type FakeIPStorage interface {
FakeIPMetadata() *FakeIPMetadata FakeIPMetadata() *FakeIPMetadata
FakeIPSaveMetadata(metadata *FakeIPMetadata) error FakeIPSaveMetadata(metadata *FakeIPMetadata) error
FakeIPStore(address netip.Addr, domain string) error FakeIPStore(address netip.Addr, domain string) error
FakeIPStoreAsync(address netip.Addr, domain string, logger logger.Logger)
FakeIPLoad(address netip.Addr) (string, bool) FakeIPLoad(address netip.Addr) (string, bool)
FakeIPLoadDomain(domain string, isIPv6 bool) (netip.Addr, bool)
FakeIPReset() error FakeIPReset() error
} }

View File

@@ -13,6 +13,7 @@ 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

View File

@@ -4,12 +4,6 @@ type PreStarter interface {
PreStart() error PreStart() error
} }
func PreStart(starter any) error { type PostStarter interface {
if preService, ok := starter.(PreStarter); ok { PostStart() error
err := preService.PreStart()
if err != nil {
return err
}
}
return nil
} }

40
box.go
View File

@@ -211,27 +211,18 @@ func (s *Box) Start() error {
func (s *Box) preStart() error { func (s *Box) preStart() error {
for serviceName, service := range s.preServices { for serviceName, service := range s.preServices {
s.logger.Trace("pre-start ", serviceName) if preService, isPreService := service.(adapter.PreStarter); isPreService {
err := adapter.PreStart(service) s.logger.Trace("pre-start ", serviceName)
if err != nil { err := preService.PreStart()
return E.Cause(err, "pre-starting ", serviceName)
}
}
for i, out := range s.outbounds {
var tag string
if out.Tag() == "" {
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 { if err != nil {
return E.Cause(err, "initialize outbound/", out.Type(), "[", tag, "]") return E.Cause(err, "pre-starting ", serviceName)
} }
} }
} }
err := s.startOutbounds()
if err != nil {
return err
}
return s.router.Start() return s.router.Start()
} }
@@ -260,13 +251,26 @@ func (s *Box) start() error {
return E.Cause(err, "initialize inbound/", in.Type(), "[", tag, "]") return E.Cause(err, "initialize inbound/", in.Type(), "[", tag, "]")
} }
} }
return nil
}
func (s *Box) postStart() error {
for serviceName, service := range s.postServices { for serviceName, service := range s.postServices {
s.logger.Trace("starting ", service) s.logger.Trace("starting ", service)
err = service.Start() err := service.Start()
if err != nil { if err != nil {
return E.Cause(err, "start ", serviceName) return E.Cause(err, "start ", serviceName)
} }
} }
for serviceName, service := range s.outbounds {
if lateService, isLateService := service.(adapter.PostStarter); isLateService {
s.logger.Trace("post-starting ", service)
err := lateService.PostStart()
if err != nil {
return E.Cause(err, "post-start ", serviceName)
}
}
}
return nil return nil
} }

79
box_outbound.go Normal file
View File

@@ -0,0 +1,79 @@
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()
}
if _, exists := outbounds[outboundTag]; exists {
return E.New("outbound tag ", outboundTag, " duplicated")
}
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

@@ -40,6 +40,7 @@ var (
sharedFlags []string sharedFlags []string
debugFlags []string debugFlags []string
sharedTags []string sharedTags []string
iosTags []string
debugTags []string debugTags []string
) )
@@ -54,7 +55,7 @@ func init() {
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_wireguard", "with_utls", "with_clash_api")
sharedTags = append(sharedTags, "test_sing_shadowsocks2") iosTags = append(iosTags, "with_dhcp", "with_low_memory", "with_conntrack")
debugTags = append(debugTags, "debug") debugTags = append(debugTags, "debug")
} }
@@ -115,7 +116,7 @@ func buildiOS() {
args = append(args, debugFlags...) args = append(args, debugFlags...)
} }
tags := append(sharedTags, "with_low_memory", "with_conntrack") tags := append(sharedTags, iosTags...)
args = append(args, "-tags") args = append(args, "-tags")
if !debugEnabled { if !debugEnabled {
args = append(args, strings.Join(tags, ",")) args = append(args, strings.Join(tags, ","))
@@ -132,7 +133,7 @@ func buildiOS() {
log.Fatal(err) log.Fatal(err)
} }
copyPath := filepath.Join("..", "sing-box-for-ios") copyPath := filepath.Join("..", "sing-box-for-apple")
if rw.FileExists(copyPath) { if rw.FileExists(copyPath) {
targetDir := filepath.Join(copyPath, "Libbox.xcframework") targetDir := filepath.Join(copyPath, "Libbox.xcframework")
targetDir, _ = filepath.Abs(targetDir) targetDir, _ = filepath.Abs(targetDir)

View File

@@ -55,7 +55,7 @@ func WrapQUIC(err error) error {
if err == nil { if err == nil {
return nil return nil
} }
if Contains(err, "canceled with error code 0") { if Contains(err, "canceled by local with error code 0") {
return net.ErrClosed return net.ErrClosed
} }
return err return err

View File

@@ -1,87 +0,0 @@
package debugio
import (
"net"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type LogConn struct {
N.ExtendedConn
logger log.Logger
prefix string
}
func NewLogConn(conn net.Conn, logger log.Logger, prefix string) N.ExtendedConn {
return &LogConn{bufio.NewExtendedConn(conn), logger, prefix}
}
func (c *LogConn) Read(p []byte) (n int, err error) {
n, err = c.ExtendedConn.Read(p)
if n > 0 {
c.logger.Debug(c.prefix, " read ", buf.EncodeHexString(p[:n]))
}
return
}
func (c *LogConn) Write(p []byte) (n int, err error) {
c.logger.Debug(c.prefix, " write ", buf.EncodeHexString(p))
return c.ExtendedConn.Write(p)
}
func (c *LogConn) ReadBuffer(buffer *buf.Buffer) error {
err := c.ExtendedConn.ReadBuffer(buffer)
if err == nil {
c.logger.Debug(c.prefix, " read buffer ", buf.EncodeHexString(buffer.Bytes()))
}
return err
}
func (c *LogConn) WriteBuffer(buffer *buf.Buffer) error {
c.logger.Debug(c.prefix, " write buffer ", buf.EncodeHexString(buffer.Bytes()))
return c.ExtendedConn.WriteBuffer(buffer)
}
func (c *LogConn) Upstream() any {
return c.ExtendedConn
}
type LogPacketConn struct {
N.NetPacketConn
logger log.Logger
prefix string
}
func NewLogPacketConn(conn net.PacketConn, logger log.Logger, prefix string) N.NetPacketConn {
return &LogPacketConn{bufio.NewPacketConn(conn), logger, prefix}
}
func (c *LogPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
n, addr, err = c.NetPacketConn.ReadFrom(p)
if n > 0 {
c.logger.Debug(c.prefix, " read from ", addr, " ", buf.EncodeHexString(p[:n]))
}
return
}
func (c *LogPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
c.logger.Debug(c.prefix, " write to ", addr, " ", buf.EncodeHexString(p))
return c.NetPacketConn.WriteTo(p, addr)
}
func (c *LogPacketConn) ReadPacket(buffer *buf.Buffer) (destination M.Socksaddr, err error) {
destination, err = c.NetPacketConn.ReadPacket(buffer)
if err == nil {
c.logger.Debug(c.prefix, " read packet from ", destination, " ", buf.EncodeHexString(buffer.Bytes()))
}
return
}
func (c *LogPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
c.logger.Debug(c.prefix, " write packet to ", destination, " ", buf.EncodeHexString(buffer.Bytes()))
return c.NetPacketConn.WritePacket(buffer, destination)
}

View File

@@ -1,19 +0,0 @@
package debugio
import (
"fmt"
"reflect"
"github.com/sagernet/sing/common"
)
func PrintUpstream(obj any) {
for obj != nil {
fmt.Println(reflect.TypeOf(obj))
if u, ok := obj.(common.WithUpstream); !ok {
break
} else {
obj = u.Upstream()
}
}
}

View File

@@ -1,48 +0,0 @@
package debugio
import (
"net"
"sync"
"github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio"
N "github.com/sagernet/sing/common/network"
)
type RaceConn struct {
N.ExtendedConn
readAccess sync.Mutex
writeAccess sync.Mutex
}
func NewRaceConn(conn net.Conn) N.ExtendedConn {
return &RaceConn{ExtendedConn: bufio.NewExtendedConn(conn)}
}
func (c *RaceConn) Read(p []byte) (n int, err error) {
c.readAccess.Lock()
defer c.readAccess.Unlock()
return c.ExtendedConn.Read(p)
}
func (c *RaceConn) Write(p []byte) (n int, err error) {
c.writeAccess.Lock()
defer c.writeAccess.Unlock()
return c.ExtendedConn.Write(p)
}
func (c *RaceConn) ReadBuffer(buffer *buf.Buffer) error {
c.readAccess.Lock()
defer c.readAccess.Unlock()
return c.ExtendedConn.ReadBuffer(buffer)
}
func (c *RaceConn) WriteBuffer(buffer *buf.Buffer) error {
c.writeAccess.Lock()
defer c.writeAccess.Unlock()
return c.ExtendedConn.WriteBuffer(buffer)
}
func (c *RaceConn) Upstream() any {
return c.ExtendedConn
}

View File

@@ -128,13 +128,6 @@ func (c *slowOpenConn) NeedHandshake() bool {
return c.conn == nil return c.conn == nil
} }
func (c *slowOpenConn) ReadFrom(r io.Reader) (n int64, err error) {
if c.conn != nil {
return bufio.Copy(c.conn, r)
}
return bufio.ReadFrom0(c, r)
}
func (c *slowOpenConn) WriteTo(w io.Writer) (n int64, err error) { func (c *slowOpenConn) WriteTo(w io.Writer) (n int64, err error) {
if c.conn == nil { if c.conn == nil {
select { select {

View File

@@ -15,7 +15,6 @@ import (
"unicode" "unicode"
"unsafe" "unsafe"
"github.com/sagernet/sing/common"
"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"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
@@ -82,9 +81,7 @@ func resolveSocketByNetlink(network string, source netip.AddrPort, destination n
return 0, 0, E.Cause(err, "write netlink request") return 0, 0, E.Cause(err, "write netlink request")
} }
_buffer := buf.StackNew() buffer := buf.New()
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release() defer buffer.Release()
n, err := syscall.Read(socket, buffer.FreeBytes()) n, err := syscall.Read(socket, buffer.FreeBytes())

View File

@@ -26,9 +26,7 @@ func StreamDomainNameQuery(readCtx context.Context, reader io.Reader) (*adapter.
if length == 0 { if length == 0 {
return nil, os.ErrInvalid return nil, os.ErrInvalid
} }
_buffer := buf.StackNewSize(int(length)) buffer := buf.NewSize(int(length))
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release() defer buffer.Release()
readCtx, cancel := context.WithTimeout(readCtx, time.Millisecond*100) readCtx, cancel := context.WithTimeout(readCtx, time.Millisecond*100)

View File

@@ -21,6 +21,7 @@ import (
type acmeWrapper struct { type acmeWrapper struct {
ctx context.Context ctx context.Context
cfg *certmagic.Config cfg *certmagic.Config
cache *certmagic.Cache
domain []string domain []string
} }
@@ -29,7 +30,7 @@ func (w *acmeWrapper) Start() error {
} }
func (w *acmeWrapper) Close() error { func (w *acmeWrapper) Close() error {
w.cfg.Unmanage(w.domain) w.cache.Stop()
return nil return nil
} }
@@ -77,10 +78,11 @@ func startACME(ctx context.Context, options option.InboundACMEOptions) (*tls.Con
acmeConfig.ExternalAccount = (*acme.EAB)(options.ExternalAccount) acmeConfig.ExternalAccount = (*acme.EAB)(options.ExternalAccount)
} }
config.Issuers = []certmagic.Issuer{certmagic.NewACMEIssuer(config, acmeConfig)} config.Issuers = []certmagic.Issuer{certmagic.NewACMEIssuer(config, acmeConfig)}
config = certmagic.New(certmagic.NewCache(certmagic.CacheOptions{ cache := certmagic.NewCache(certmagic.CacheOptions{
GetConfigForCert: func(certificate certmagic.Certificate) (*certmagic.Config, error) { GetConfigForCert: func(certificate certmagic.Certificate) (*certmagic.Config, error) {
return config, nil return config, nil
}, },
}), *config) })
return config.TLSConfig(), &acmeWrapper{ctx, config, options.Domain}, nil config = certmagic.New(cache, *config)
return config.TLSConfig(), &acmeWrapper{ctx: ctx, cfg: config, cache: cache, domain: options.Domain}, nil
} }

View File

@@ -10,6 +10,7 @@ import (
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"
"github.com/sagernet/sing/common/x/list"
) )
type History struct { type History struct {
@@ -20,6 +21,7 @@ type History struct {
type HistoryStorage struct { type HistoryStorage struct {
access sync.RWMutex access sync.RWMutex
delayHistory map[string]*History delayHistory map[string]*History
callbacks list.List[func()]
} }
func NewHistoryStorage() *HistoryStorage { func NewHistoryStorage() *HistoryStorage {
@@ -28,6 +30,18 @@ func NewHistoryStorage() *HistoryStorage {
} }
} }
func (s *HistoryStorage) AddListener(listener func()) *list.Element[func()] {
s.access.Lock()
defer s.access.Unlock()
return s.callbacks.PushBack(listener)
}
func (s *HistoryStorage) RemoveListener(element *list.Element[func()]) {
s.access.Lock()
defer s.access.Unlock()
s.callbacks.Remove(element)
}
func (s *HistoryStorage) LoadURLTestHistory(tag string) *History { func (s *HistoryStorage) LoadURLTestHistory(tag string) *History {
if s == nil { if s == nil {
return nil return nil
@@ -39,14 +53,24 @@ func (s *HistoryStorage) LoadURLTestHistory(tag string) *History {
func (s *HistoryStorage) DeleteURLTestHistory(tag string) { func (s *HistoryStorage) DeleteURLTestHistory(tag string) {
s.access.Lock() s.access.Lock()
defer s.access.Unlock()
delete(s.delayHistory, tag) delete(s.delayHistory, tag)
s.access.Unlock()
s.notifyUpdated()
} }
func (s *HistoryStorage) StoreURLTestHistory(tag string, history *History) { func (s *HistoryStorage) StoreURLTestHistory(tag string, history *History) {
s.access.Lock() s.access.Lock()
defer s.access.Unlock()
s.delayHistory[tag] = history s.delayHistory[tag] = history
s.access.Unlock()
s.notifyUpdated()
}
func (s *HistoryStorage) notifyUpdated() {
s.access.RLock()
defer s.access.RUnlock()
for element := s.callbacks.Front(); element != nil; element = element.Next() {
element.Value()
}
} }
func URLTest(ctx context.Context, link string, detour N.Dialer) (t uint16, err error) { func URLTest(ctx context.Context, link string, detour N.Dialer) (t uint16, err error) {

View File

@@ -1,3 +1,86 @@
#### 1.3.4
* Fixes and improvements
* We're now on the [App Store](https://apps.apple.com/us/app/sing-box/id6451272673), always free! It should be noted that due to stricter and slower review, the release of Store versions will be delayed.
* We've made a standalone version of the macOS client (the original Application Extension relies on App Store distribution), which you can download as SFM-version-universal.zip in the release artifacts.
#### 1.3.3
* Fixes and improvements
#### 1.3.1-rc.1
* Fix bugs and update dependencies
#### 1.3.1-beta.3
* Introducing our [new iOS](/installation/clients/sfi) and [macOS](/installation/clients/sfm) client applications **1**
* Fixes and improvements
**1**:
The old testflight link and app are no longer valid.
#### 1.3.1-beta.2
* Fix bugs and update dependencies
#### 1.3.1-beta.1
* Fixes and improvements
#### 1.3.0
* Fix bugs and update dependencies
Important changes since 1.2:
* Add [FakeIP](/configuration/dns/fakeip) support **1**
* Improve multiplex **2**
* Add [DNS reverse mapping](/configuration/dns#reverse_mapping) support
* Add `rewrite_ttl` DNS rule action
* Add `store_fakeip` Clash API option
* Add multi-peer support for [WireGuard](/configuration/outbound/wireguard#peers) outbound
* Add loopback detect
* Add Clash.Meta API compatibility for Clash API
* Download Yacd-meta by default if the specified Clash `external_ui` directory is empty
* Add path and headers option for HTTP outbound
* Perform URLTest recheck after network changes
* Fix `system` tun stack for ios
* Fix network monitor for android/ios
* Update VLESS and XUDP protocol
* Make splice work with traffic statistics systems like Clash API
* Significantly reduces memory usage of idle connections
* Improve DNS caching
* Add `independent_cache` [option](/configuration/dns#independent_cache) for DNS
* Reimplemented shadowsocks client
* Add multiplex support for VLESS outbound
* Automatically add Windows firewall rules in order for the system tun stack to work
* Fix TLS 1.2 support for shadow-tls client
* Add `cache_id` [option](/configuration/experimental#cache_id) for Clash cache file
* Fix `local` DNS transport for Android
*1*:
See [FAQ](/faq/fakeip) for more information.
*2*:
Added new `h2mux` multiplex protocol and `padding` multiplex option, see [Multiplex](/configuration/shared/multiplex).
#### 1.3-rc2
* Fix `local` DNS transport for Android
* Fix bugs and update dependencies
#### 1.3-rc1
* Fix bugs and update dependencies
#### 1.3-beta14
* Fixes and improvements
#### 1.3-beta13 #### 1.3-beta13
* Fix resolving fakeip domains **1** * Fix resolving fakeip domains **1**

View File

@@ -9,7 +9,8 @@ Experimental iOS client for sing-box.
#### Download #### Download
* [TestFlight](https://testflight.apple.com/join/c6ylui2j) * [AppStore](https://apps.apple.com/us/app/sing-box/id6451272673)
* [TestFlight](https://testflight.apple.com/join/AcqO44FH)
#### Note #### Note

View File

@@ -9,7 +9,8 @@
#### 下载 #### 下载
* [TestFlight](https://testflight.apple.com/join/c6ylui2j) * [AppStore](https://apps.apple.com/us/app/sing-box/id6451272673)
* [TestFlight](https://testflight.apple.com/join/AcqO44FH)
#### 注意事项 #### 注意事项

View File

@@ -0,0 +1,22 @@
# SFM
Experimental macOS client for sing-box.
#### Requirements
* macOS 13.0+
#### Download
* [AppStore](https://apps.apple.com/us/app/sing-box/id6451272673)
* [TestFlight](https://testflight.apple.com/join/AcqO44FH)
#### Note
* User Agent in remote profile request is `SFM/$version ($version_code; sing-box $sing_box_version)`
* Crash logs is located in `Settings` -> `View Service Log`
#### Privacy policy
* SFI did not collect or share personal data.
* The data generated by the software is always on your device.

View File

@@ -0,0 +1,22 @@
# SFM
实验性的 macOS sing-box 客户端。
#### 要求
* macOS 13.0+
#### 下载
* [AppStore](https://apps.apple.com/us/app/sing-box/id6451272673)
* [TestFlight](https://testflight.apple.com/join/AcqO44FH)
#### 注意事项
* 远程配置文件请求中的 User Agent 为 `SFM/$version ($version_code; sing-box $sing_box_version)`
* 崩溃日志位于 `设置` -> `查看服务日志`
#### 隐私政策
* SFM 不收集或共享个人数据。
* 软件生成的数据始终在您的设备上。

View File

@@ -1,8 +1,4 @@
#### Github Github Issue: [Issues · SagerNet/sing-box](https://github.com/SagerNet/sing-box/issues)
Telegram Notification channel: [@yapnc](https://t.me/yapnc)
Issue: [Issues · SagerNet/sing-box](https://github.com/SagerNet/sing-box/issues) Telegram User group: [@yapug](https://t.me/yapug)
Email: [contact@sagernet.org](mailto:contact@sagernet.org)
#### Telegram
Notification channel: [@yapnc](https://t.me/yapnc)
User group: [@yapug](https://t.me/yapug)

View File

@@ -1,8 +1,4 @@
#### Github Github 工单: [Issues · SagerNet/sing-box](https://github.com/SagerNet/sing-box/issues)
Telegram 通知频道: [@yapnc](https://t.me/yapnc)
工单: [Issues · SagerNet/sing-box](https://github.com/SagerNet/sing-box/issues) Telegram 用户组: [@yapug](https://t.me/yapug)
Email: [contact@sagernet.org](mailto:contact@sagernet.org)
#### Telegram
通知频道: [@yapnc](https://t.me/yapnc)
用户组: [@yapug](https://t.me/yapug)

View File

@@ -1,7 +1,10 @@
package cachefile package cachefile
import ( import (
"net/netip"
"os" "os"
"strings"
"sync"
"time" "time"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
@@ -14,8 +17,12 @@ var bucketSelected = []byte("selected")
var _ adapter.ClashCacheFile = (*CacheFile)(nil) var _ adapter.ClashCacheFile = (*CacheFile)(nil)
type CacheFile struct { type CacheFile struct {
DB *bbolt.DB DB *bbolt.DB
cacheID []byte cacheID []byte
saveAccess sync.RWMutex
saveDomain map[netip.Addr]string
saveAddress4 map[string]netip.Addr
saveAddress6 map[string]netip.Addr
} }
func Open(path string, cacheID string) (*CacheFile, error) { func Open(path string, cacheID string) (*CacheFile, error) {
@@ -36,7 +43,41 @@ func Open(path string, cacheID string) (*CacheFile, error) {
if cacheID != "" { if cacheID != "" {
cacheIDBytes = append([]byte{0}, []byte(cacheID)...) cacheIDBytes = append([]byte{0}, []byte(cacheID)...)
} }
return &CacheFile{db, cacheIDBytes}, nil err = db.Batch(func(tx *bbolt.Tx) error {
return tx.ForEach(func(name []byte, b *bbolt.Bucket) error {
if name[0] == 0 {
return b.ForEachBucket(func(k []byte) error {
bucketName := string(k)
if !(bucketName == string(bucketSelected)) {
delErr := b.DeleteBucket(name)
if delErr != nil {
return delErr
}
}
return nil
})
} else {
bucketName := string(name)
if !(bucketName == string(bucketSelected) || strings.HasPrefix(bucketName, fakeipBucketPrefix)) {
delErr := tx.DeleteBucket(name)
if delErr != nil {
return delErr
}
}
}
return nil
})
})
if err != nil {
return nil, err
}
return &CacheFile{
DB: db,
cacheID: cacheIDBytes,
saveDomain: make(map[netip.Addr]string),
saveAddress4: make(map[string]netip.Addr),
saveAddress6: make(map[string]netip.Addr),
}, nil
} }
func (c *CacheFile) bucket(t *bbolt.Tx, key []byte) *bbolt.Bucket { func (c *CacheFile) bucket(t *bbolt.Tx, key []byte) *bbolt.Bucket {

View File

@@ -5,18 +5,24 @@ import (
"os" "os"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
"go.etcd.io/bbolt" "go.etcd.io/bbolt"
) )
const fakeipBucketPrefix = "fakeip_"
var ( var (
bucketFakeIP = []byte("fakeip") bucketFakeIP = []byte(fakeipBucketPrefix + "address")
keyMetadata = []byte("metadata") bucketFakeIPDomain4 = []byte(fakeipBucketPrefix + "domain4")
bucketFakeIPDomain6 = []byte(fakeipBucketPrefix + "domain6")
keyMetadata = []byte(fakeipBucketPrefix + "metadata")
) )
func (c *CacheFile) FakeIPMetadata() *adapter.FakeIPMetadata { func (c *CacheFile) FakeIPMetadata() *adapter.FakeIPMetadata {
var metadata adapter.FakeIPMetadata var metadata adapter.FakeIPMetadata
err := c.DB.View(func(tx *bbolt.Tx) error { err := c.DB.Batch(func(tx *bbolt.Tx) error {
bucket := tx.Bucket(bucketFakeIP) bucket := tx.Bucket(bucketFakeIP)
if bucket == nil { if bucket == nil {
return nil return nil
@@ -25,6 +31,10 @@ func (c *CacheFile) FakeIPMetadata() *adapter.FakeIPMetadata {
if len(metadataBinary) == 0 { if len(metadataBinary) == 0 {
return os.ErrInvalid return os.ErrInvalid
} }
err := bucket.Delete(keyMetadata)
if err != nil {
return err
}
return metadata.UnmarshalBinary(metadataBinary) return metadata.UnmarshalBinary(metadataBinary)
}) })
if err != nil { if err != nil {
@@ -53,11 +63,54 @@ func (c *CacheFile) FakeIPStore(address netip.Addr, domain string) error {
if err != nil { if err != nil {
return err return err
} }
return bucket.Put(address.AsSlice(), []byte(domain)) err = bucket.Put(address.AsSlice(), []byte(domain))
if err != nil {
return err
}
if address.Is4() {
bucket, err = tx.CreateBucketIfNotExists(bucketFakeIPDomain4)
} else {
bucket, err = tx.CreateBucketIfNotExists(bucketFakeIPDomain6)
}
if err != nil {
return err
}
return bucket.Put([]byte(domain), address.AsSlice())
}) })
} }
func (c *CacheFile) FakeIPStoreAsync(address netip.Addr, domain string, logger logger.Logger) {
c.saveAccess.Lock()
c.saveDomain[address] = domain
if address.Is4() {
c.saveAddress4[domain] = address
} else {
c.saveAddress6[domain] = address
}
c.saveAccess.Unlock()
go func() {
err := c.FakeIPStore(address, domain)
if err != nil {
logger.Warn("save FakeIP address pair: ", err)
}
c.saveAccess.Lock()
delete(c.saveDomain, address)
if address.Is4() {
delete(c.saveAddress4, domain)
} else {
delete(c.saveAddress6, domain)
}
c.saveAccess.Unlock()
}()
}
func (c *CacheFile) FakeIPLoad(address netip.Addr) (string, bool) { func (c *CacheFile) FakeIPLoad(address netip.Addr) (string, bool) {
c.saveAccess.RLock()
cachedDomain, cached := c.saveDomain[address]
c.saveAccess.RUnlock()
if cached {
return cachedDomain, true
}
var domain string var domain string
_ = c.DB.View(func(tx *bbolt.Tx) error { _ = c.DB.View(func(tx *bbolt.Tx) error {
bucket := tx.Bucket(bucketFakeIP) bucket := tx.Bucket(bucketFakeIP)
@@ -70,8 +123,48 @@ func (c *CacheFile) FakeIPLoad(address netip.Addr) (string, bool) {
return domain, domain != "" return domain, domain != ""
} }
func (c *CacheFile) FakeIPLoadDomain(domain string, isIPv6 bool) (netip.Addr, bool) {
var (
cachedAddress netip.Addr
cached bool
)
c.saveAccess.RLock()
if !isIPv6 {
cachedAddress, cached = c.saveAddress4[domain]
} else {
cachedAddress, cached = c.saveAddress6[domain]
}
c.saveAccess.RUnlock()
if cached {
return cachedAddress, true
}
var address netip.Addr
_ = c.DB.View(func(tx *bbolt.Tx) error {
var bucket *bbolt.Bucket
if isIPv6 {
bucket = tx.Bucket(bucketFakeIPDomain6)
} else {
bucket = tx.Bucket(bucketFakeIPDomain4)
}
if bucket == nil {
return nil
}
address = M.AddrFromIP(bucket.Get([]byte(domain)))
return nil
})
return address, address.IsValid()
}
func (c *CacheFile) FakeIPReset() error { func (c *CacheFile) FakeIPReset() error {
return c.DB.Batch(func(tx *bbolt.Tx) error { return c.DB.Batch(func(tx *bbolt.Tx) error {
return tx.DeleteBucket(bucketFakeIP) err := tx.DeleteBucket(bucketFakeIP)
if err != nil {
return err
}
err = tx.DeleteBucket(bucketFakeIPDomain4)
if err != nil {
return err
}
return tx.DeleteBucket(bucketFakeIPDomain6)
}) })
} }

View File

@@ -7,6 +7,15 @@ type Map[K comparable, V any] struct {
m sync.Map m sync.Map
} }
func (m *Map[K, V]) Len() int {
var count int
m.m.Range(func(key, value any) bool {
count++
return true
})
return count
}
func (m *Map[K, V]) Load(key K) (V, bool) { func (m *Map[K, V]) Load(key K) (V, bool) {
v, ok := m.m.Load(key) v, ok := m.m.Load(key)
if !ok { if !ok {

View File

@@ -23,6 +23,7 @@ import (
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format" F "github.com/sagernet/sing/common/format"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/service"
"github.com/sagernet/sing/service/filemanager" "github.com/sagernet/sing/service/filemanager"
"github.com/sagernet/websocket" "github.com/sagernet/websocket"
@@ -68,13 +69,16 @@ func NewServer(ctx context.Context, router adapter.Router, logFactory log.Observ
Handler: chiRouter, Handler: chiRouter,
}, },
trafficManager: trafficManager, trafficManager: trafficManager,
urlTestHistory: urltest.NewHistoryStorage(),
mode: strings.ToLower(options.DefaultMode), mode: strings.ToLower(options.DefaultMode),
storeSelected: options.StoreSelected, storeSelected: options.StoreSelected,
storeFakeIP: options.StoreFakeIP, storeFakeIP: options.StoreFakeIP,
externalUIDownloadURL: options.ExternalUIDownloadURL, externalUIDownloadURL: options.ExternalUIDownloadURL,
externalUIDownloadDetour: options.ExternalUIDownloadDetour, externalUIDownloadDetour: options.ExternalUIDownloadDetour,
} }
server.urlTestHistory = service.PtrFromContext[urltest.HistoryStorage](ctx)
if server.urlTestHistory == nil {
server.urlTestHistory = urltest.NewHistoryStorage()
}
if server.mode == "" { if server.mode == "" {
server.mode = "rule" server.mode = "rule"
} }
@@ -185,6 +189,10 @@ func (s *Server) HistoryStorage() *urltest.HistoryStorage {
return s.urlTestHistory return s.urlTestHistory
} }
func (s *Server) TrafficManager() *trafficontrol.Manager {
return s.trafficManager
}
func (s *Server) RoutedConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, matchedRule adapter.Rule) (net.Conn, adapter.Tracker) { func (s *Server) RoutedConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, matchedRule adapter.Rule) (net.Conn, adapter.Tracker) {
tracker := trafficontrol.NewTCPTracker(conn, s.trafficManager, castMetadata(metadata), s.router, matchedRule) tracker := trafficontrol.NewTCPTracker(conn, s.trafficManager, castMetadata(metadata), s.router, matchedRule)
return tracker, tracker return tracker, tracker

View File

@@ -55,6 +55,14 @@ func (m *Manager) Now() (up int64, down int64) {
return m.uploadBlip.Load(), m.downloadBlip.Load() return m.uploadBlip.Load(), m.downloadBlip.Load()
} }
func (m *Manager) Total() (up int64, down int64) {
return m.uploadTotal.Load(), m.downloadTotal.Load()
}
func (m *Manager) Connections() int {
return m.connections.Len()
}
func (m *Manager) Snapshot() *Snapshot { func (m *Manager) Snapshot() *Snapshot {
var connections []tracker var connections []tracker
m.connections.Range(func(_ string, value tracker) bool { m.connections.Range(func(_ string, value tracker) bool {

View File

@@ -3,7 +3,9 @@ package libbox
const ( const (
CommandLog int32 = iota CommandLog int32 = iota
CommandStatus CommandStatus
CommandServiceStop
CommandServiceReload CommandServiceReload
CommandCloseConnections CommandCloseConnections
CommandGroup
CommandSelectOutbound
CommandURLTest
) )

View File

@@ -26,6 +26,13 @@ type CommandClientHandler interface {
Disconnected(message string) Disconnected(message string)
WriteLog(message string) WriteLog(message string)
WriteStatus(message *StatusMessage) WriteStatus(message *StatusMessage)
WriteGroups(message OutboundGroupIterator)
}
func NewStandaloneCommandClient(sharedDirectory string) *CommandClient {
return &CommandClient{
sharedDirectory: sharedDirectory,
}
} }
func NewCommandClient(sharedDirectory string, handler CommandClientHandler, options *CommandClientOptions) *CommandClient { func NewCommandClient(sharedDirectory string, handler CommandClientHandler, options *CommandClientOptions) *CommandClient {
@@ -36,16 +43,16 @@ func NewCommandClient(sharedDirectory string, handler CommandClientHandler, opti
} }
} }
func clientConnect(sharedDirectory string) (net.Conn, error) { func (c *CommandClient) directConnect() (net.Conn, error) {
return net.DialUnix("unix", nil, &net.UnixAddr{ return net.DialUnix("unix", nil, &net.UnixAddr{
Name: filepath.Join(sharedDirectory, "command.sock"), Name: filepath.Join(c.sharedDirectory, "command.sock"),
Net: "unix", Net: "unix",
}) })
} }
func (c *CommandClient) Connect() error { func (c *CommandClient) Connect() error {
common.Close(c.conn) common.Close(c.conn)
conn, err := clientConnect(c.sharedDirectory) conn, err := c.directConnect()
if err != nil { if err != nil {
return err return err
} }
@@ -65,6 +72,13 @@ func (c *CommandClient) Connect() error {
} }
c.handler.Connected() c.handler.Connected()
go c.handleStatusConn(conn) go c.handleStatusConn(conn)
case CommandGroup:
err = binary.Write(conn, binary.BigEndian, c.options.StatusInterval)
if err != nil {
return E.Cause(err, "write interval")
}
c.handler.Connected()
go c.handleGroupConn(conn)
} }
return nil return nil
} }

View File

@@ -9,8 +9,8 @@ import (
"github.com/sagernet/sing-box/common/dialer/conntrack" "github.com/sagernet/sing-box/common/dialer/conntrack"
) )
func ClientCloseConnections(sharedDirectory string) error { func (c *CommandClient) CloseConnections() error {
conn, err := clientConnect(sharedDirectory) conn, err := c.directConnect()
if err != nil { if err != nil {
return err return err
} }

View File

@@ -0,0 +1,228 @@
package libbox
import (
"encoding/binary"
"io"
"net"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/urltest"
"github.com/sagernet/sing-box/outbound"
"github.com/sagernet/sing/common/rw"
"github.com/sagernet/sing/service"
)
type OutboundGroup struct {
Tag string
Type string
Selectable bool
Selected string
items []*OutboundGroupItem
}
func (g *OutboundGroup) GetItems() OutboundGroupItemIterator {
return newIterator(g.items)
}
type OutboundGroupIterator interface {
Next() *OutboundGroup
HasNext() bool
}
type OutboundGroupItem struct {
Tag string
Type string
URLTestTime int64
URLTestDelay int32
}
type OutboundGroupItemIterator interface {
Next() *OutboundGroupItem
HasNext() bool
}
func (c *CommandClient) handleGroupConn(conn net.Conn) {
defer conn.Close()
for {
groups, err := readGroups(conn)
if err != nil {
c.handler.Disconnected(err.Error())
return
}
c.handler.WriteGroups(groups)
}
}
func (s *CommandServer) handleGroupConn(conn net.Conn) error {
defer conn.Close()
ctx := connKeepAlive(conn)
for {
service := s.service
if service != nil {
err := writeGroups(conn, service)
if err != nil {
return err
}
} else {
err := binary.Write(conn, binary.BigEndian, uint16(0))
if err != nil {
return err
}
}
select {
case <-ctx.Done():
return ctx.Err()
case <-s.urlTestUpdate:
}
}
}
func readGroups(reader io.Reader) (OutboundGroupIterator, error) {
var groupLength uint16
err := binary.Read(reader, binary.BigEndian, &groupLength)
if err != nil {
return nil, err
}
groups := make([]*OutboundGroup, 0, groupLength)
for i := 0; i < int(groupLength); i++ {
var group OutboundGroup
group.Tag, err = rw.ReadVString(reader)
if err != nil {
return nil, err
}
group.Type, err = rw.ReadVString(reader)
if err != nil {
return nil, err
}
err = binary.Read(reader, binary.BigEndian, &group.Selectable)
if err != nil {
return nil, err
}
group.Selected, err = rw.ReadVString(reader)
if err != nil {
return nil, err
}
var itemLength uint16
err = binary.Read(reader, binary.BigEndian, &itemLength)
if err != nil {
return nil, err
}
group.items = make([]*OutboundGroupItem, itemLength)
for j := 0; j < int(itemLength); j++ {
var item OutboundGroupItem
item.Tag, err = rw.ReadVString(reader)
if err != nil {
return nil, err
}
item.Type, err = rw.ReadVString(reader)
if err != nil {
return nil, err
}
err = binary.Read(reader, binary.BigEndian, &item.URLTestTime)
if err != nil {
return nil, err
}
err = binary.Read(reader, binary.BigEndian, &item.URLTestDelay)
if err != nil {
return nil, err
}
group.items[j] = &item
}
groups = append(groups, &group)
}
return newIterator(groups), nil
}
func writeGroups(writer io.Writer, boxService *BoxService) error {
historyStorage := service.PtrFromContext[urltest.HistoryStorage](boxService.ctx)
outbounds := boxService.instance.Router().Outbounds()
var iGroups []adapter.OutboundGroup
for _, it := range outbounds {
if group, isGroup := it.(adapter.OutboundGroup); isGroup {
iGroups = append(iGroups, group)
}
}
var groups []OutboundGroup
for _, iGroup := range iGroups {
var group OutboundGroup
group.Tag = iGroup.Tag()
group.Type = iGroup.Type()
_, group.Selectable = iGroup.(*outbound.Selector)
group.Selected = iGroup.Now()
for _, itemTag := range iGroup.All() {
itemOutbound, isLoaded := boxService.instance.Router().Outbound(itemTag)
if !isLoaded {
continue
}
var item OutboundGroupItem
item.Tag = itemTag
item.Type = itemOutbound.Type()
if history := historyStorage.LoadURLTestHistory(adapter.OutboundTag(itemOutbound)); history != nil {
item.URLTestTime = history.Time.Unix()
item.URLTestDelay = int32(history.Delay)
}
group.items = append(group.items, &item)
}
groups = append(groups, group)
}
err := binary.Write(writer, binary.BigEndian, uint16(len(groups)))
if err != nil {
return err
}
for _, group := range groups {
err = rw.WriteVString(writer, group.Tag)
if err != nil {
return err
}
err = rw.WriteVString(writer, group.Type)
if err != nil {
return err
}
err = binary.Write(writer, binary.BigEndian, group.Selectable)
if err != nil {
return err
}
err = rw.WriteVString(writer, group.Selected)
if err != nil {
return err
}
err = binary.Write(writer, binary.BigEndian, uint16(len(group.items)))
if err != nil {
return err
}
for _, item := range group.items {
err = rw.WriteVString(writer, item.Tag)
if err != nil {
return err
}
err = rw.WriteVString(writer, item.Type)
if err != nil {
return err
}
err = binary.Write(writer, binary.BigEndian, item.URLTestTime)
if err != nil {
return err
}
err = binary.Write(writer, binary.BigEndian, item.URLTestDelay)
if err != nil {
return err
}
}
}
return nil
}

View File

@@ -11,7 +11,7 @@ func (s *CommandServer) WriteMessage(message string) {
s.subscriber.Emit(message) s.subscriber.Emit(message)
s.access.Lock() s.access.Lock()
s.savedLines.PushBack(message) s.savedLines.PushBack(message)
if s.savedLines.Len() > 100 { if s.savedLines.Len() > s.maxLines {
s.savedLines.Remove(s.savedLines.Front()) s.savedLines.Remove(s.savedLines.Front())
} }
s.access.Unlock() s.access.Unlock()

View File

@@ -8,8 +8,8 @@ import (
"github.com/sagernet/sing/common/rw" "github.com/sagernet/sing/common/rw"
) )
func ClientServiceReload(sharedDirectory string) error { func (c *CommandClient) ServiceReload() error {
conn, err := clientConnect(sharedDirectory) conn, err := c.directConnect()
if err != nil { if err != nil {
return err return err
} }

View File

@@ -0,0 +1,59 @@
package libbox
import (
"encoding/binary"
"net"
"github.com/sagernet/sing-box/outbound"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/rw"
)
func (c *CommandClient) SelectOutbound(groupTag string, outboundTag string) error {
conn, err := c.directConnect()
if err != nil {
return err
}
defer conn.Close()
err = binary.Write(conn, binary.BigEndian, uint8(CommandSelectOutbound))
if err != nil {
return err
}
err = rw.WriteVString(conn, groupTag)
if err != nil {
return err
}
err = rw.WriteVString(conn, outboundTag)
if err != nil {
return err
}
return readError(conn)
}
func (s *CommandServer) handleSelectOutbound(conn net.Conn) error {
defer conn.Close()
groupTag, err := rw.ReadVString(conn)
if err != nil {
return err
}
outboundTag, err := rw.ReadVString(conn)
if err != nil {
return err
}
service := s.service
if service == nil {
return writeError(conn, E.New("service not ready"))
}
outboundGroup, isLoaded := service.instance.Router().Outbound(groupTag)
if !isLoaded {
return writeError(conn, E.New("selector not found: ", groupTag))
}
selector, isSelector := outboundGroup.(*outbound.Selector)
if !isSelector {
return writeError(conn, E.New("outbound is not a selector: ", groupTag))
}
if !selector.SelectOutbound(outboundTag) {
return writeError(conn, E.New("outbound not found in selector: ", outboundTag))
}
return writeError(conn, nil)
}

View File

@@ -7,12 +7,14 @@ import (
"path/filepath" "path/filepath"
"sync" "sync"
"github.com/sagernet/sing-box/common/urltest"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/debug" "github.com/sagernet/sing/common/debug"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/observable" "github.com/sagernet/sing/common/observable"
"github.com/sagernet/sing/common/x/list" "github.com/sagernet/sing/common/x/list"
"github.com/sagernet/sing/service"
) )
type CommandServer struct { type CommandServer struct {
@@ -22,26 +24,51 @@ type CommandServer struct {
access sync.Mutex access sync.Mutex
savedLines *list.List[string] savedLines *list.List[string]
maxLines int
subscriber *observable.Subscriber[string] subscriber *observable.Subscriber[string]
observer *observable.Observer[string] observer *observable.Observer[string]
service *BoxService
urlTestListener *list.Element[func()]
urlTestUpdate chan struct{}
} }
type CommandServerHandler interface { type CommandServerHandler interface {
ServiceStop() error
ServiceReload() error ServiceReload() error
} }
func NewCommandServer(sharedDirectory string, handler CommandServerHandler) *CommandServer { func NewCommandServer(sharedDirectory string, handler CommandServerHandler, maxLines int32) *CommandServer {
server := &CommandServer{ server := &CommandServer{
sockPath: filepath.Join(sharedDirectory, "command.sock"), sockPath: filepath.Join(sharedDirectory, "command.sock"),
handler: handler, handler: handler,
savedLines: new(list.List[string]), savedLines: new(list.List[string]),
subscriber: observable.NewSubscriber[string](128), maxLines: int(maxLines),
subscriber: observable.NewSubscriber[string](128),
urlTestUpdate: make(chan struct{}, 1),
} }
server.observer = observable.NewObserver[string](server.subscriber, 64) server.observer = observable.NewObserver[string](server.subscriber, 64)
return server return server
} }
func (s *CommandServer) SetService(newService *BoxService) {
if s.service != nil && s.listener != nil {
service.PtrFromContext[urltest.HistoryStorage](s.service.ctx).RemoveListener(s.urlTestListener)
s.urlTestListener = nil
}
s.service = newService
if newService != nil {
s.urlTestListener = service.PtrFromContext[urltest.HistoryStorage](newService.ctx).AddListener(s.notifyURLTestUpdate)
}
s.notifyURLTestUpdate()
}
func (s *CommandServer) notifyURLTestUpdate() {
select {
case s.urlTestUpdate <- struct{}{}:
default:
}
}
func (s *CommandServer) Start() error { func (s *CommandServer) Start() error {
os.Remove(s.sockPath) os.Remove(s.sockPath)
listener, err := net.ListenUnix("unix", &net.UnixAddr{ listener, err := net.ListenUnix("unix", &net.UnixAddr{
@@ -51,6 +78,14 @@ func (s *CommandServer) Start() error {
if err != nil { if err != nil {
return err return err
} }
if sUserID > 0 {
err = os.Chown(s.sockPath, sUserID, sGroupID)
if err != nil {
listener.Close()
os.Remove(s.sockPath)
return err
}
}
s.listener = listener s.listener = listener
go s.loopConnection(listener) go s.loopConnection(listener)
return nil return nil
@@ -92,12 +127,16 @@ func (s *CommandServer) handleConnection(conn net.Conn) error {
return s.handleLogConn(conn) return s.handleLogConn(conn)
case CommandStatus: case CommandStatus:
return s.handleStatusConn(conn) return s.handleStatusConn(conn)
case CommandServiceStop:
return s.handleServiceStop(conn)
case CommandServiceReload: case CommandServiceReload:
return s.handleServiceReload(conn) return s.handleServiceReload(conn)
case CommandCloseConnections: case CommandCloseConnections:
return s.handleCloseConnections(conn) return s.handleCloseConnections(conn)
case CommandGroup:
return s.handleGroupConn(conn)
case CommandSelectOutbound:
return s.handleSelectOutbound(conn)
case CommandURLTest:
return s.handleURLTest(conn)
default: default:
return E.New("unknown command: ", command) return E.New("unknown command: ", command)
} }

View File

@@ -0,0 +1,39 @@
package libbox
import (
"encoding/binary"
"io"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/rw"
)
func readError(reader io.Reader) error {
var hasError bool
err := binary.Read(reader, binary.BigEndian, &hasError)
if err != nil {
return err
}
if hasError {
errorMessage, err := rw.ReadVString(reader)
if err != nil {
return err
}
return E.New(errorMessage)
}
return nil
}
func writeError(writer io.Writer, wErr error) error {
err := binary.Write(writer, binary.BigEndian, wErr != nil)
if err != nil {
return err
}
if wErr != nil {
err = rw.WriteVString(writer, wErr.Error())
if err != nil {
return err
}
}
return nil
}

View File

@@ -7,22 +7,40 @@ import (
"time" "time"
"github.com/sagernet/sing-box/common/dialer/conntrack" "github.com/sagernet/sing-box/common/dialer/conntrack"
"github.com/sagernet/sing-box/experimental/clashapi"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
) )
type StatusMessage struct { type StatusMessage struct {
Memory int64 Memory int64
Goroutines int32 Goroutines int32
Connections int32 ConnectionsIn int32
ConnectionsOut int32
TrafficAvailable bool
Uplink int64
Downlink int64
UplinkTotal int64
DownlinkTotal int64
} }
func readStatus() StatusMessage { func (s *CommandServer) readStatus() StatusMessage {
var memStats runtime.MemStats var memStats runtime.MemStats
runtime.ReadMemStats(&memStats) runtime.ReadMemStats(&memStats)
var message StatusMessage var message StatusMessage
message.Memory = int64(memStats.StackInuse + memStats.HeapInuse + memStats.HeapIdle - memStats.HeapReleased) message.Memory = int64(memStats.StackInuse + memStats.HeapInuse + memStats.HeapIdle - memStats.HeapReleased)
message.Goroutines = int32(runtime.NumGoroutine()) message.Goroutines = int32(runtime.NumGoroutine())
message.Connections = int32(conntrack.Count()) message.ConnectionsOut = int32(conntrack.Count())
if s.service != nil {
if clashServer := s.service.instance.Router().ClashServer(); clashServer != nil {
message.TrafficAvailable = true
trafficManager := clashServer.(*clashapi.Server).TrafficManager()
message.Uplink, message.Downlink = trafficManager.Now()
message.UplinkTotal, message.DownlinkTotal = trafficManager.Total()
message.ConnectionsIn = int32(trafficManager.Connections())
}
}
return message return message
} }
@@ -36,7 +54,7 @@ func (s *CommandServer) handleStatusConn(conn net.Conn) error {
defer ticker.Stop() defer ticker.Stop()
ctx := connKeepAlive(conn) ctx := connKeepAlive(conn)
for { for {
err = binary.Write(conn, binary.BigEndian, readStatus()) err = binary.Write(conn, binary.BigEndian, s.readStatus())
if err != nil { if err != nil {
return err return err
} }

View File

@@ -1,48 +0,0 @@
package libbox
import (
"encoding/binary"
"net"
"runtime/debug"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/rw"
)
func ClientServiceStop(sharedDirectory string) error {
conn, err := clientConnect(sharedDirectory)
if err != nil {
return err
}
defer conn.Close()
err = binary.Write(conn, binary.BigEndian, uint8(CommandServiceStop))
if err != nil {
return err
}
var hasError bool
err = binary.Read(conn, binary.BigEndian, &hasError)
if err != nil {
return err
}
if hasError {
errorMessage, err := rw.ReadVString(conn)
if err != nil {
return err
}
return E.New(errorMessage)
}
return nil
}
func (s *CommandServer) handleServiceStop(conn net.Conn) error {
rErr := s.handler.ServiceStop()
err := binary.Write(conn, binary.BigEndian, rErr != nil)
if err != nil {
return err
}
if rErr != nil {
return rw.WriteVString(conn, rErr.Error())
}
debug.FreeOSMemory()
return nil
}

View File

@@ -0,0 +1,95 @@
package libbox
import (
"encoding/binary"
"net"
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/urltest"
"github.com/sagernet/sing-box/outbound"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/batch"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/rw"
)
func (c *CommandClient) URLTest(groupTag string) error {
conn, err := c.directConnect()
if err != nil {
return err
}
defer conn.Close()
err = binary.Write(conn, binary.BigEndian, uint8(CommandURLTest))
if err != nil {
return err
}
err = rw.WriteVString(conn, groupTag)
if err != nil {
return err
}
return readError(conn)
}
func (s *CommandServer) handleURLTest(conn net.Conn) error {
defer conn.Close()
groupTag, err := rw.ReadVString(conn)
if err != nil {
return err
}
service := s.service
if service == nil {
return nil
}
abstractOutboundGroup, isLoaded := service.instance.Router().Outbound(groupTag)
if !isLoaded {
return writeError(conn, E.New("outbound group not found: ", groupTag))
}
outboundGroup, isOutboundGroup := abstractOutboundGroup.(adapter.OutboundGroup)
if !isOutboundGroup {
return writeError(conn, E.New("outbound is not a group: ", groupTag))
}
urlTest, isURLTest := abstractOutboundGroup.(*outbound.URLTest)
if isURLTest {
go urlTest.CheckOutbounds()
} else {
var historyStorage *urltest.HistoryStorage
if clashServer := service.instance.Router().ClashServer(); clashServer != nil {
historyStorage = clashServer.HistoryStorage()
} else {
return writeError(conn, E.New("Clash API is required for URLTest on non-URLTest group"))
}
outbounds := common.Filter(common.Map(outboundGroup.All(), func(it string) adapter.Outbound {
itOutbound, _ := service.instance.Router().Outbound(it)
return itOutbound
}), func(it adapter.Outbound) bool {
if it == nil {
return false
}
_, isGroup := it.(adapter.OutboundGroup)
if isGroup {
return false
}
return true
})
b, _ := batch.New(service.ctx, batch.WithConcurrencyNum[any](10))
for _, detour := range outbounds {
outboundToTest := detour
outboundTag := outboundToTest.Tag()
b.Go(outboundTag, func() (any, error) {
t, err := urltest.URLTest(service.ctx, "", outboundToTest)
if err != nil {
historyStorage.DeleteURLTestHistory(outboundTag)
} else {
historyStorage.StoreURLTestHistory(outboundTag, &urltest.History{
Time: time.Now(),
Delay: t,
})
}
return nil, nil
})
}
}
return writeError(conn, nil)
}

162
experimental/libbox/dns.go Normal file
View File

@@ -0,0 +1,162 @@
package libbox
import (
"context"
"net/netip"
"strings"
"syscall"
"github.com/sagernet/sing-dns"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/task"
mDNS "github.com/miekg/dns"
)
type LocalDNSTransport interface {
Raw() bool
Lookup(ctx *ExchangeContext, network string, domain string) error
Exchange(ctx *ExchangeContext, message []byte) error
}
func RegisterLocalDNSTransport(transport LocalDNSTransport) {
if transport == nil {
dns.RegisterTransport([]string{"local"}, dns.CreateLocalTransport)
} else {
dns.RegisterTransport([]string{"local"}, func(name string, ctx context.Context, logger logger.ContextLogger, dialer N.Dialer, link string) (dns.Transport, error) {
return &platformLocalDNSTransport{
iif: transport,
}, nil
})
}
}
var _ dns.Transport = (*platformLocalDNSTransport)(nil)
type platformLocalDNSTransport struct {
iif LocalDNSTransport
}
func (p *platformLocalDNSTransport) Name() string {
return "local"
}
func (p *platformLocalDNSTransport) Start() error {
return nil
}
func (p *platformLocalDNSTransport) Close() error {
return nil
}
func (p *platformLocalDNSTransport) Raw() bool {
return p.iif.Raw()
}
func (p *platformLocalDNSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
messageBytes, err := message.Pack()
if err != nil {
return nil, err
}
response := &ExchangeContext{
context: ctx,
}
var responseMessage *mDNS.Msg
return responseMessage, task.Run(ctx, func() error {
err = p.iif.Exchange(response, messageBytes)
if err != nil {
return err
}
if response.error != nil {
return response.error
}
responseMessage = &response.message
return nil
})
}
func (p *platformLocalDNSTransport) Lookup(ctx context.Context, domain string, strategy dns.DomainStrategy) ([]netip.Addr, error) {
var network string
switch strategy {
case dns.DomainStrategyUseIPv4:
network = "ip4"
case dns.DomainStrategyPreferIPv6:
network = "ip6"
default:
network = "ip"
}
response := &ExchangeContext{
context: ctx,
}
var responseAddr []netip.Addr
return responseAddr, task.Run(ctx, func() error {
err := p.iif.Lookup(response, network, domain)
if err != nil {
return err
}
if response.error != nil {
return response.error
}
switch strategy {
case dns.DomainStrategyUseIPv4:
responseAddr = common.Filter(response.addresses, func(it netip.Addr) bool {
return it.Is4()
})
case dns.DomainStrategyPreferIPv6:
responseAddr = common.Filter(response.addresses, func(it netip.Addr) bool {
return it.Is6()
})
default:
responseAddr = response.addresses
}
/*if len(responseAddr) == 0 {
response.error = dns.RCodeSuccess
}*/
return nil
})
}
type Func interface {
Invoke() error
}
type ExchangeContext struct {
context context.Context
message mDNS.Msg
addresses []netip.Addr
error error
}
func (c *ExchangeContext) OnCancel(callback Func) {
go func() {
<-c.context.Done()
callback.Invoke()
}()
}
func (c *ExchangeContext) Success(result string) {
c.addresses = common.Map(common.Filter(strings.Split(result, "\n"), func(it string) bool {
return !common.IsEmpty(it)
}), func(it string) netip.Addr {
return M.ParseSocksaddrHostPort(it, 0).Unwrap().Addr
})
}
func (c *ExchangeContext) RawSuccess(result []byte) {
err := c.message.Unpack(result)
if err != nil {
c.error = E.Cause(err, "parse response")
}
}
func (c *ExchangeContext) ErrorCode(code int32) {
c.error = dns.RCodeError(code)
}
func (c *ExchangeContext) ErrnoCode(code int32) {
c.error = syscall.Errno(code)
}

View File

@@ -18,29 +18,13 @@ func RedirectStderr(path string) error {
if err != nil { if err != nil {
return err return err
} }
err = unix.Dup2(int(outputFile.Fd()), int(os.Stderr.Fd())) if sUserID > 0 {
if err != nil { err = outputFile.Chown(sUserID, sGroupID)
outputFile.Close() if err != nil {
os.Remove(outputFile.Name()) outputFile.Close()
return err os.Remove(outputFile.Name())
} return err
stderrFile = outputFile }
return nil
}
func RedirectStderrAsUser(path string, uid, gid int) error {
if stats, err := os.Stat(path); err == nil && stats.Size() > 0 {
_ = os.Rename(path, path+".old")
}
outputFile, err := os.Create(path)
if err != nil {
return err
}
err = outputFile.Chown(uid, gid)
if err != nil {
outputFile.Close()
os.Remove(outputFile.Name())
return err
} }
err = unix.Dup2(int(outputFile.Fd()), int(os.Stderr.Fd())) err = unix.Dup2(int(outputFile.Fd()), int(os.Stderr.Fd()))
if err != nil { if err != nil {

View File

@@ -1,18 +1,22 @@
//go:build darwin
package libbox package libbox
import ( import (
"math"
runtimeDebug "runtime/debug" runtimeDebug "runtime/debug"
"github.com/sagernet/sing-box/common/dialer/conntrack" "github.com/sagernet/sing-box/common/dialer/conntrack"
) )
const memoryLimit = 30 * 1024 * 1024 func SetMemoryLimit(enabled bool) {
const memoryLimit = 30 * 1024 * 1024
func SetMemoryLimit() { if enabled {
runtimeDebug.SetGCPercent(10) runtimeDebug.SetGCPercent(10)
runtimeDebug.SetMemoryLimit(memoryLimit) runtimeDebug.SetMemoryLimit(memoryLimit)
conntrack.KillerEnabled = true conntrack.KillerEnabled = true
conntrack.MemoryLimit = memoryLimit conntrack.MemoryLimit = memoryLimit
} else {
runtimeDebug.SetGCPercent(100)
runtimeDebug.SetMemoryLimit(math.MaxInt64)
conntrack.KillerEnabled = false
}
} }

View File

@@ -8,6 +8,7 @@ import (
"github.com/sagernet/sing-box" "github.com/sagernet/sing-box"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/process" "github.com/sagernet/sing-box/common/process"
"github.com/sagernet/sing-box/common/urltest"
"github.com/sagernet/sing-box/experimental/libbox/internal/procfs" "github.com/sagernet/sing-box/experimental/libbox/internal/procfs"
"github.com/sagernet/sing-box/experimental/libbox/platform" "github.com/sagernet/sing-box/experimental/libbox/platform"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
@@ -16,6 +17,7 @@ import (
"github.com/sagernet/sing/common/control" "github.com/sagernet/sing/common/control"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/service"
"github.com/sagernet/sing/service/filemanager" "github.com/sagernet/sing/service/filemanager"
) )
@@ -32,6 +34,7 @@ func NewService(configContent string, platformInterface PlatformInterface) (*Box
} }
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
ctx = filemanager.WithDefault(ctx, sBasePath, sTempPath, sUserID, sGroupID) ctx = filemanager.WithDefault(ctx, sBasePath, sTempPath, sUserID, sGroupID)
ctx = service.ContextWithPtr(ctx, urltest.NewHistoryStorage())
instance, err := box.New(box.Options{ instance, err := box.New(box.Options{
Context: ctx, Context: ctx,
Options: options, Options: options,

View File

@@ -2,6 +2,8 @@ package libbox
import ( import (
"os" "os"
"os/user"
"strconv"
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
@@ -15,17 +17,23 @@ var (
sGroupID int sGroupID int
) )
func Setup(basePath string, tempPath string, userID int, groupID int) { func Setup(basePath string, tempPath string) {
sBasePath = basePath sBasePath = basePath
sTempPath = tempPath sTempPath = tempPath
sUserID = userID sUserID = os.Getuid()
sGroupID = groupID sGroupID = os.Getgid()
if sUserID == -1 { }
sUserID = os.Getuid()
} func SetupWithUsername(basePath string, tempPath string, username string) error {
if sGroupID == -1 { sBasePath = basePath
sGroupID = os.Getgid() sTempPath = tempPath
sUser, err := user.Lookup(username)
if err != nil {
return err
} }
sUserID, _ = strconv.Atoi(sUser.Uid)
sGroupID, _ = strconv.Atoi(sUser.Gid)
return nil
} }
func Version() string { func Version() string {

70
go.mod
View File

@@ -4,35 +4,35 @@ go 1.18
require ( require (
berty.tech/go-libtor v1.0.385 berty.tech/go-libtor v1.0.385
github.com/Dreamacro/clash v1.16.0 github.com/Dreamacro/clash v1.17.0
github.com/caddyserver/certmagic v0.18.0 github.com/caddyserver/certmagic v0.19.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
github.com/go-chi/chi/v5 v5.0.8 github.com/go-chi/chi/v5 v5.0.10
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.3
github.com/gofrs/uuid/v5 v5.0.0 github.com/gofrs/uuid/v5 v5.0.0
github.com/insomniacslk/dhcp v0.0.0-20230516061539-49801966e6cb github.com/insomniacslk/dhcp v0.0.0-20230612134759-b20c9ba983df
github.com/logrusorgru/aurora v2.0.3+incompatible github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/mholt/acmez v1.1.1 github.com/mholt/acmez v1.2.0
github.com/miekg/dns v1.1.54 github.com/miekg/dns v1.1.55
github.com/ooni/go-libtor v1.1.8 github.com/ooni/go-libtor v1.1.8
github.com/oschwald/maxminddb-golang v1.10.0 github.com/oschwald/maxminddb-golang v1.11.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-20230701084532-493ee2e45182
github.com/sagernet/gvisor v0.0.0-20230611140528-4411f7659a08 github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 github.com/sagernet/quic-go v0.0.0-20230615020047-10f05c797c02
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.20230611070640-2812461739c3 github.com/sagernet/sing v0.2.9
github.com/sagernet/sing-dns v0.1.5-0.20230426113254-25d948c44223 github.com/sagernet/sing-dns v0.1.8
github.com/sagernet/sing-mux v0.0.0-20230517134606-1ebe6bb26646 github.com/sagernet/sing-mux v0.1.2
github.com/sagernet/sing-shadowsocks v0.2.2-0.20230509053848-d83f8fe1194c github.com/sagernet/sing-shadowsocks v0.2.4
github.com/sagernet/sing-shadowsocks2 v0.0.0-20230608022204-942fbd98f846 github.com/sagernet/sing-shadowsocks2 v0.1.3
github.com/sagernet/sing-shadowtls v0.1.2-0.20230531025805-ebadc7615da3 github.com/sagernet/sing-shadowtls v0.1.4
github.com/sagernet/sing-tun v0.1.5-0.20230611140633-41b2639e1385 github.com/sagernet/sing-tun v0.1.11
github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3 github.com/sagernet/sing-vmess v0.1.7
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
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2
@@ -43,26 +43,25 @@ require (
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.9.0 golang.org/x/crypto v0.11.0
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df
golang.org/x/net v0.10.0 golang.org/x/net v0.12.0
golang.org/x/sys v0.8.0 golang.org/x/sys v0.10.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.55.0 google.golang.org/grpc v1.56.2
google.golang.org/protobuf v1.30.0 google.golang.org/protobuf v1.31.0
) )
//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/Dreamacro/protobytes v0.0.0-20230617041236-6500a9f4f158 // 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
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
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/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/google/btree v1.1.2 // 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
@@ -70,7 +69,7 @@ require (
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.2.4 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // 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
@@ -79,22 +78,23 @@ require (
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
github.com/quic-go/qtls-go1-19 v0.2.0 // indirect github.com/quic-go/qtls-go1-19 v0.3.2 // indirect
github.com/quic-go/qtls-go1-20 v0.1.0 // indirect github.com/quic-go/qtls-go1-20 v0.2.2 // indirect
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 // indirect github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 // indirect
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
github.com/zeebo/blake3 v0.2.3 // indirect
go.uber.org/atomic v1.11.0 // indirect go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/mod v0.10.0 // indirect golang.org/x/mod v0.11.0 // indirect
golang.org/x/text v0.9.0 // indirect golang.org/x/text v0.11.0 // indirect
golang.org/x/time v0.3.0 // indirect golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.8.0 // indirect golang.org/x/tools v0.10.0 // indirect
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // 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.2.1 // indirect
) )

169
go.sum
View File

@@ -1,16 +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.16.0 h1:Ve+8mvtsCv7ySa6f53/GOW6Tho0AFp5RNFsgQZFKcZs= github.com/Dreamacro/clash v1.17.0 h1:LWtp6KcnrCiujY58ufI8pylI+hbCBgSCsLI90EWhpi4=
github.com/Dreamacro/clash v1.16.0/go.mod h1:ZM3UI2gqqUN7UL7L/F9aTHODTByya6sbC/WivQpaoJk= github.com/Dreamacro/clash v1.17.0/go.mod h1:PtcAft7sdsK325BD6uwm8wvhOkMV3TCeED6dfZ/lnfE=
github.com/Dreamacro/protobytes v0.0.0-20230324064118-87bc784139cd h1:ygk7IF14j4ep4H2ZyeDe3IEoMZF8JdbX851RVVa/4D8= github.com/Dreamacro/protobytes v0.0.0-20230617041236-6500a9f4f158 h1:JFnwKplz9hj8ubqYjm8HkgZS1Rvz9yW+u/XCNNTxr0k=
github.com/Dreamacro/protobytes v0.0.0-20230324064118-87bc784139cd/go.mod h1:QvmEZ/h6KXszPOr2wUFl7Zn3hfFNYdfbXwPVDTyZs6k= github.com/Dreamacro/protobytes v0.0.0-20230617041236-6500a9f4f158/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.18.0 h1:L22mJES1WllfLoHUcQUy4wVO7UfOsoL5wtg/Bj7kmIw= github.com/caddyserver/certmagic v0.19.0 h1:HuJ1Yf1H1jAfmBGrSSQN1XRkafnWcpDtyIiyMV6vmpM=
github.com/caddyserver/certmagic v0.18.0/go.mod h1:e0YLTnXIopZ05bBWCLzpIf1Yvk27Q90FGUmGowFRDY8= github.com/caddyserver/certmagic v0.19.0/go.mod h1:fsL01NomQ6N+kE2j37ZCnig2MFosG+MIO4ztnmG/zz8=
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=
@@ -27,12 +27,12 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0= github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-chi/render v1.0.2 h1:4ER/udB0+fMWB2Jlf15RV3F4A2FDuYi/9f+lFttR/Lg= github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
github.com/go-chi/render v1.0.2/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0= github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
@@ -40,7 +40,6 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg78
github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M= github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
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/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.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
@@ -55,16 +54,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-20230516061539-49801966e6cb h1:6fDKEAXwe3rsfS4khW3EZ8kEqmSiV9szhMPcDrD+Y7Q= github.com/insomniacslk/dhcp v0.0.0-20230612134759-b20c9ba983df h1:pF1MMIzEJzJ/MyI4bXYXVYyN8CJgoQ2PPKT2z3O/Cl4=
github.com/insomniacslk/dhcp v0.0.0-20230516061539-49801966e6cb/go.mod h1:7474bZ1YNCvarT6WFKie4kEET6J0KYRDC4XJqqXzQW4= github.com/insomniacslk/dhcp v0.0.0-20230612134759-b20c9ba983df/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.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
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=
@@ -72,10 +71,10 @@ 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.1 h1:sYeeYd/EHVm9cSmLdWey5oW/fXFVAq5pNLjSczN2ZUg= github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
github.com/mholt/acmez v1.1.1/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE= github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo=
github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/miekg/dns v1.1.55/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=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI= github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
@@ -83,8 +82,8 @@ github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7
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.8 h1:Wo3V3DVTxl5vZdxtQakqYP+DAHx7pPtAFSl1bnAa08w= github.com/ooni/go-libtor v1.1.8 h1:Wo3V3DVTxl5vZdxtQakqYP+DAHx7pPtAFSl1bnAa08w=
github.com/ooni/go-libtor v1.1.8/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.11.0 h1:aSXMqYR/EPNjGE8epgqwDay+P30hCBZIveY0WZbAWh0=
github.com/oschwald/maxminddb-golang v1.10.0/go.mod h1:Y2ELenReaLAZ0b400URyGwvYxHV1dLIxBuyOsyYjHK0= github.com/oschwald/maxminddb-golang v1.11.0/go.mod h1:YmVI+H0zh3ySFR3w+oz8PCfglAFj3PuCmui13+P9zDg=
github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE= github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE=
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs= github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
@@ -97,43 +96,43 @@ github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
github.com/quic-go/qtls-go1-18 v0.2.0 h1:5ViXqBZ90wpUcZS0ge79rf029yx0dYB0McyPJwqqj7U= github.com/quic-go/qtls-go1-18 v0.2.0 h1:5ViXqBZ90wpUcZS0ge79rf029yx0dYB0McyPJwqqj7U=
github.com/quic-go/qtls-go1-18 v0.2.0/go.mod h1:moGulGHK7o6O8lSPSZNoOwcLvJKJ85vVNc7oJFD65bc= github.com/quic-go/qtls-go1-18 v0.2.0/go.mod h1:moGulGHK7o6O8lSPSZNoOwcLvJKJ85vVNc7oJFD65bc=
github.com/quic-go/qtls-go1-19 v0.2.0 h1:Cvn2WdhyViFUHoOqK52i51k4nDX8EwIh5VJiVM4nttk= github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U=
github.com/quic-go/qtls-go1-19 v0.2.0/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI=
github.com/quic-go/qtls-go1-20 v0.1.0 h1:d1PK3ErFy9t7zxKsG3NXBJXZjp/kMLoIb3y/kV54oAI= github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E=
github.com/quic-go/qtls-go1-20 v0.1.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0 h1:KyhtFFt1Jtp5vW2ohNvstvQffTOQ/s5vENuGXzdA+TM= github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0 h1:KyhtFFt1Jtp5vW2ohNvstvQffTOQ/s5vENuGXzdA+TM=
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0/go.mod h1:D4SFEOkJK+4W1v86ZhX0jPM0rAL498fyQAChqMtes/I= github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0/go.mod h1:D4SFEOkJK+4W1v86ZhX0jPM0rAL498fyQAChqMtes/I=
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA= github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA=
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-20230701084532-493ee2e45182 h1:sD5g92IO15RAX2DvA4Cq3Uc7tcgqNWVi8K3VTCI6sEo=
github.com/sagernet/gomobile v0.0.0-20230413023804-244d7ff07035/go.mod h1:5YE39YkJkCcMsfq1jMKkjsrM2GfBoF9JVWnvU89hmvU= github.com/sagernet/gomobile v0.0.0-20230701084532-493ee2e45182/go.mod h1:5YE39YkJkCcMsfq1jMKkjsrM2GfBoF9JVWnvU89hmvU=
github.com/sagernet/gvisor v0.0.0-20230611140528-4411f7659a08 h1:p1z8y0tXLCKSiJ7GbUlaYPhyEbWL8LKLMYFpVxRVsBg= github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2 h1:dnkKrzapqtAwjTSWt6hdPrARORfoYvuUczynvRLrueo=
github.com/sagernet/gvisor v0.0.0-20230611140528-4411f7659a08/go.mod h1:FgbjODax/nj7J2lr7+rqe88vHs0Ts93pC9na5ZiG9wg= github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2/go.mod h1:1JUiV7nGuf++YFm9eWZ8q2lrwHmhcUGzptMl/vL1+LA=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE= github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 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-20230615020047-10f05c797c02 h1:9S+L1n/4hbe1pCLNTZnnddSNseQda8tuSm/+uRy6p8s=
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32/go.mod h1:QMCkxXAC3CvBgDZVIJp43NWTuwGBScCzMLVLynjERL8= github.com/sagernet/quic-go v0.0.0-20230615020047-10f05c797c02/go.mod h1:rth94YcHJfkC4mG03JTXmv7mJsDc8MOIIqQrCtoaV4U=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
github.com/sagernet/sing v0.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.20230611070640-2812461739c3 h1:OnlfGM8HncECbFiV4s6uAX961fm2UpEKSCXYBLZ1Chg= github.com/sagernet/sing v0.2.9 h1:3wsTz+JG5Wzy65eZnh6AuCrD2QqcRF6Iq6f7ttmJsAo=
github.com/sagernet/sing v0.2.5-0.20230611070640-2812461739c3/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= github.com/sagernet/sing v0.2.9/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.8 h1:zTYnxzA7mssg/Lwd70+RFPi8i3djioGnVS7zKwSF6cg=
github.com/sagernet/sing-dns v0.1.5-0.20230426113254-25d948c44223/go.mod h1:ZKuuqgsHRxDahYrzgSgy4vIAGGuKPlIf4hLcNzYzLkY= github.com/sagernet/sing-dns v0.1.8/go.mod h1:lHv8WMl9GKfMV8Wt1AJTtjVTF/h5/owpGY2YutYZF6g=
github.com/sagernet/sing-mux v0.0.0-20230517134606-1ebe6bb26646 h1:X3ADfMqeGns1Q1FlXc9kaL9FwW1UM6D6tEQo8jFstpc= github.com/sagernet/sing-mux v0.1.2 h1:av2/m6e+Gh+ECTuJZqYCjJz55BNkot0VyRMkREqyF/g=
github.com/sagernet/sing-mux v0.0.0-20230517134606-1ebe6bb26646/go.mod h1:pF+RnLvCAOhECrvauy6LYOpBakJ/vuaF1Wm4lPsWryI= github.com/sagernet/sing-mux v0.1.2/go.mod h1:r2V8AlOzXaRCHXK7fILCUGzuI2iILweTaG8C5xlpHxo=
github.com/sagernet/sing-shadowsocks v0.2.2-0.20230509053848-d83f8fe1194c h1:EiQ+i4gdPpSI8D2YUlOeBZA3R1ZGi0ShSLSXoSd/13A= github.com/sagernet/sing-shadowsocks v0.2.4 h1:s/CqXlvFAZhlIoHWUwPw5CoNnQ9Ibki9pckjuugtVfY=
github.com/sagernet/sing-shadowsocks v0.2.2-0.20230509053848-d83f8fe1194c/go.mod h1:UJjvQGw0lyYaDGIDvUraL16fwaAEH1WFw1Y6sUcMPog= github.com/sagernet/sing-shadowsocks v0.2.4/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM=
github.com/sagernet/sing-shadowsocks2 v0.0.0-20230608022204-942fbd98f846 h1:aiEEbDyPS/IFx0V9RNa1yLdxHHegNP+q7JFpST/8D5I= github.com/sagernet/sing-shadowsocks2 v0.1.3 h1:WXoLvCFi5JTFBRYorf1YePGYIQyJ/zbsBM6Fwbl5kGA=
github.com/sagernet/sing-shadowsocks2 v0.0.0-20230608022204-942fbd98f846/go.mod h1:i6Eoor37Cy4JKBcelMMFfUVBNjqRYuvcqOBjUI3Zw80= github.com/sagernet/sing-shadowsocks2 v0.1.3/go.mod h1:DOhJc/cLeqRv0wuePrQso+iUmDxOnWF4eT/oMcRzYFw=
github.com/sagernet/sing-shadowtls v0.1.2-0.20230531025805-ebadc7615da3 h1:PNwJs1F+3e/iZguYQR7YzxsH8Sm0Eu7vVuHawD89r34= github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
github.com/sagernet/sing-shadowtls v0.1.2-0.20230531025805-ebadc7615da3/go.mod h1:oG8bPerYI6cZ74KquY3DvA7ynECyrILPBnce6wtBqeI= github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4=
github.com/sagernet/sing-tun v0.1.5-0.20230611140633-41b2639e1385 h1:iKDIJB05yHyUE57VYlamGhCEauXssIukB/xZsLmP7ic= github.com/sagernet/sing-tun v0.1.11 h1:wUfRQZ4eHk8suHkGKEFxjV5uXl3tfZhPm/v14/4lHvk=
github.com/sagernet/sing-tun v0.1.5-0.20230611140633-41b2639e1385/go.mod h1:8amChfsau8s/hkooIVIU4uw7VavgrfHrT0KUbJo4ROc= github.com/sagernet/sing-tun v0.1.11/go.mod h1:XsyIVKd/Qp+2SdLZWGbavHtcpE7J7XU3S1zJmcoj9Ck=
github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3 h1:BHOnxrbC929JonuKqFdJ7ZbDp7zs4oTlH5KFvKtWu9U= github.com/sagernet/sing-vmess v0.1.7 h1:TM8FFLsXmlXH9XT8/oDgc6PC5BOzrg6OzyEe01is2r4=
github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3/go.mod h1:yKrAr+dqZd64DxBXCHWrYicp+n4qbqO73mtwv3dck8U= github.com/sagernet/sing-vmess v0.1.7/go.mod h1:1qkC1L1T2sxnS/NuO6HU72S8TkltV+EXoKGR29m/Yss=
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as= github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as=
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37/go.mod h1:3skNSftZDJWTGVtVaM2jfbce8qHnmH/AGDRe62iNOg0= github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37/go.mod h1:3skNSftZDJWTGVtVaM2jfbce8qHnmH/AGDRe62iNOg0=
github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 h1:2ItpW1nMNkPzmBTxV0/eClCklHrFSQMnUGcpUmJxVeE= github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 h1:2ItpW1nMNkPzmBTxV0/eClCklHrFSQMnUGcpUmJxVeE=
@@ -160,7 +159,12 @@ github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 h1:tHNk7XK9GkmKUR6Gh8gV
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=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg=
github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ=
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
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.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
@@ -172,72 +176,53 @@ 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=
go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35/go.mod h1:TQvodOM+hJTioNQJilmLXu08JNb8i+ccq418+KWu1/Y= go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35/go.mod h1:TQvodOM+hJTioNQJilmLXu08JNb8i+ccq418+KWu1/Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
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-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.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= golang.org/x/mod v0.11.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-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-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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-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-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/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-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.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.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.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
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.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/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.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
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-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.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-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI=
google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -245,5 +230,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=
lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=

View File

@@ -38,9 +38,7 @@ func (a *myInboundAdapter) ListenUDP() (net.PacketConn, error) {
func (a *myInboundAdapter) loopUDPIn() { func (a *myInboundAdapter) loopUDPIn() {
defer close(a.packetOutboundClosed) defer close(a.packetOutboundClosed)
_buffer := buf.StackNewPacket() buffer := buf.NewPacket()
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release() defer buffer.Release()
buffer.IncRef() buffer.IncRef()
defer buffer.DecRef() defer buffer.DecRef()
@@ -67,9 +65,7 @@ func (a *myInboundAdapter) loopUDPIn() {
func (a *myInboundAdapter) loopUDPOOBIn() { func (a *myInboundAdapter) loopUDPOOBIn() {
defer close(a.packetOutboundClosed) defer close(a.packetOutboundClosed)
_buffer := buf.StackNewPacket() buffer := buf.NewPacket()
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release() defer buffer.Release()
buffer.IncRef() buffer.IncRef()
defer buffer.DecRef() defer buffer.DecRef()

View File

@@ -35,7 +35,7 @@ type Hysteria struct {
xplusKey []byte xplusKey []byte
sendBPS uint64 sendBPS uint64
recvBPS uint64 recvBPS uint64
listener quic.Listener listener *quic.Listener
udpAccess sync.RWMutex udpAccess sync.RWMutex
udpSessionId uint32 udpSessionId uint32
udpSessions map[uint32]chan *hysteria.UDPMessage udpSessions map[uint32]chan *hysteria.UDPMessage
@@ -283,6 +283,7 @@ func (h *Hysteria) acceptStream(ctx context.Context, conn quic.Connection, strea
metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr()).Unwrap() metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr()).Unwrap()
metadata.OriginDestination = M.SocksaddrFromNet(conn.LocalAddr()).Unwrap() metadata.OriginDestination = M.SocksaddrFromNet(conn.LocalAddr()).Unwrap()
metadata.Destination = M.ParseSocksaddrHostPort(request.Host, request.Port).Unwrap() metadata.Destination = M.ParseSocksaddrHostPort(request.Host, request.Port).Unwrap()
metadata.User, _ = auth.UserFromContext[string](ctx)
if !request.UDP { if !request.UDP {
err = hysteria.WriteServerResponse(stream, hysteria.ServerResponse{ err = hysteria.WriteServerResponse(stream, hysteria.ServerResponse{
@@ -332,7 +333,7 @@ func (h *Hysteria) Close() error {
h.udpAccess.Unlock() h.udpAccess.Unlock()
return common.Close( return common.Close(
&h.myInboundAdapter, &h.myInboundAdapter,
h.listener, common.PtrOrNil(h.listener),
h.tlsConfig, h.tlsConfig,
) )
} }

View File

@@ -270,9 +270,7 @@ func (c *naiveH1Conn) read(p []byte) (n int, err error) {
if len(p) >= 3 { if len(p) >= 3 {
paddingHdr = p[:3] paddingHdr = p[:3]
} else { } else {
_paddingHdr := make([]byte, 3) paddingHdr = make([]byte, 3)
defer common.KeepAlive(_paddingHdr)
paddingHdr = common.Dup(_paddingHdr)
} }
_, err = io.ReadFull(c.Conn, paddingHdr) _, err = io.ReadFull(c.Conn, paddingHdr)
if err != nil { if err != nil {
@@ -320,9 +318,7 @@ func (c *naiveH1Conn) write(p []byte) (n int, err error) {
if c.writePadding < kFirstPaddings { if c.writePadding < kFirstPaddings {
paddingSize := rand.Intn(256) paddingSize := rand.Intn(256)
_buffer := buf.StackNewSize(3 + len(p) + paddingSize) buffer := buf.NewSize(3 + len(p) + paddingSize)
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release() defer buffer.Release()
header := buffer.Extend(3) header := buffer.Extend(3)
binary.BigEndian.PutUint16(header, uint16(len(p))) binary.BigEndian.PutUint16(header, uint16(len(p)))
@@ -449,9 +445,7 @@ func (c *naiveH2Conn) read(p []byte) (n int, err error) {
if len(p) >= 3 { if len(p) >= 3 {
paddingHdr = p[:3] paddingHdr = p[:3]
} else { } else {
_paddingHdr := make([]byte, 3) paddingHdr = make([]byte, 3)
defer common.KeepAlive(_paddingHdr)
paddingHdr = common.Dup(_paddingHdr)
} }
_, err = io.ReadFull(c.reader, paddingHdr) _, err = io.ReadFull(c.reader, paddingHdr)
if err != nil { if err != nil {
@@ -502,9 +496,7 @@ func (c *naiveH2Conn) write(p []byte) (n int, err error) {
if c.writePadding < kFirstPaddings { if c.writePadding < kFirstPaddings {
paddingSize := rand.Intn(256) paddingSize := rand.Intn(256)
_buffer := buf.StackNewSize(3 + len(p) + paddingSize) buffer := buf.NewSize(3 + len(p) + paddingSize)
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release() defer buffer.Release()
header := buffer.Extend(3) header := buffer.Extend(3)
binary.BigEndian.PutUint16(header, uint16(len(p))) binary.BigEndian.PutUint16(header, uint16(len(p)))

View File

@@ -24,8 +24,9 @@ func NewFactory(formatter Formatter, writer io.Writer, platformWriter io.Writer)
return &simpleFactory{ return &simpleFactory{
formatter: formatter, formatter: formatter,
platformFormatter: Formatter{ platformFormatter: Formatter{
BaseTime: formatter.BaseTime, BaseTime: formatter.BaseTime,
DisableColors: C.IsDarwin || C.IsIos, DisableColors: C.IsDarwin || C.IsIos,
DisableLineBreak: true,
}, },
writer: writer, writer: writer,
platformWriter: platformWriter, platformWriter: platformWriter,

View File

@@ -17,6 +17,7 @@ type Formatter struct {
DisableTimestamp bool DisableTimestamp bool
FullTimestamp bool FullTimestamp bool
TimestampFormat string TimestampFormat string
DisableLineBreak bool
} }
func (f Formatter) Format(ctx context.Context, level Level, tag string, message string, timestamp time.Time) string { func (f Formatter) Format(ctx context.Context, level Level, tag string, message string, timestamp time.Time) string {
@@ -76,8 +77,14 @@ func (f Formatter) Format(ctx context.Context, level Level, tag string, message
default: default:
message = levelString + "[" + xd(int(timestamp.Sub(f.BaseTime)/time.Second), 4) + "] " + message message = levelString + "[" + xd(int(timestamp.Sub(f.BaseTime)/time.Second), 4) + "] " + message
} }
if message[len(message)-1] != '\n' { if f.DisableLineBreak {
message += "\n" if message[len(message)-1] == '\n' {
message = message[:len(message)-1]
}
} else {
if message[len(message)-1] != '\n' {
message += "\n"
}
} }
return message return message
} }

View File

@@ -28,8 +28,9 @@ func NewObservableFactory(formatter Formatter, writer io.Writer, platformWriter
factory := &observableFactory{ factory := &observableFactory{
formatter: formatter, formatter: formatter,
platformFormatter: Formatter{ platformFormatter: Formatter{
BaseTime: formatter.BaseTime, BaseTime: formatter.BaseTime,
DisableColors: C.IsDarwin || C.IsIos, DisableColors: C.IsDarwin || C.IsIos,
DisableLineBreak: true,
}, },
writer: writer, writer: writer,
platformWriter: platformWriter, platformWriter: platformWriter,

View File

@@ -39,6 +39,7 @@ nav:
- From source: installation/from-source.md - From source: installation/from-source.md
- Clients: - Clients:
- iOS: installation/clients/sfi.md - iOS: installation/clients/sfi.md
- macOS: installation/clients/sfm.md
- Android: installation/clients/sfa.md - Android: installation/clients/sfa.md
- Configuration: - Configuration:
- configuration/index.md - configuration/index.md

View File

@@ -5,12 +5,12 @@ import (
"net" "net"
"net/netip" "net/netip"
"os" "os"
"runtime"
"time" "time"
"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 +20,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 +40,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
@@ -99,8 +111,7 @@ func CopyEarlyConn(ctx context.Context, conn net.Conn, serverConn net.Conn) erro
} }
} }
if earlyConn, isEarlyConn := common.Cast[N.EarlyConn](serverConn); isEarlyConn && earlyConn.NeedHandshake() { if earlyConn, isEarlyConn := common.Cast[N.EarlyConn](serverConn); isEarlyConn && earlyConn.NeedHandshake() {
_payload := buf.StackNew() payload := buf.NewPacket()
payload := common.Dup(_payload)
err := conn.SetReadDeadline(time.Now().Add(C.ReadPayloadTimeout)) err := conn.SetReadDeadline(time.Now().Add(C.ReadPayloadTimeout))
if err != os.ErrInvalid { if err != os.ErrInvalid {
if err != nil { if err != nil {
@@ -120,7 +131,6 @@ func CopyEarlyConn(ctx context.Context, conn net.Conn, serverConn net.Conn) erro
if err != nil { if err != nil {
return N.HandshakeFailure(conn, err) return N.HandshakeFailure(conn, err)
} }
runtime.KeepAlive(_payload)
payload.Release() payload.Release()
} }
return bufio.CopyConn(ctx, conn, serverConn) return bufio.CopyConn(ctx, conn, serverConn)

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

@@ -65,9 +65,7 @@ func (d *DNS) handleConnection(ctx context.Context, conn net.Conn, metadata adap
if queryLength == 0 { if queryLength == 0 {
return dns.RCodeFormatError return dns.RCodeFormatError
} }
_buffer := buf.StackNewSize(int(queryLength)) buffer := buf.NewSize(int(queryLength))
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release() defer buffer.Release()
_, err = buffer.ReadFullFrom(conn, int(queryLength)) _, err = buffer.ReadFullFrom(conn, int(queryLength))
if err != nil { if err != nil {
@@ -84,9 +82,7 @@ func (d *DNS) handleConnection(ctx context.Context, conn net.Conn, metadata adap
if err != nil { if err != nil {
return err return err
} }
_responseBuffer := buf.StackNewPacket() responseBuffer := buf.NewPacket()
defer common.KeepAlive(_responseBuffer)
responseBuffer := common.Dup(_responseBuffer)
defer responseBuffer.Release() defer responseBuffer.Release()
responseBuffer.Resize(2, 0) responseBuffer.Resize(2, 0)
n, err := response.PackBuffer(responseBuffer.FreeBytes()) n, err := response.PackBuffer(responseBuffer.FreeBytes())

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),
@@ -177,7 +178,7 @@ func (h *Hysteria) offerNew(ctx context.Context) (quic.Connection, error) {
packetConn = hysteria.NewXPlusPacketConn(packetConn, h.xplusKey) packetConn = hysteria.NewXPlusPacketConn(packetConn, h.xplusKey)
} }
packetConn = &hysteria.PacketConnWrapper{PacketConn: packetConn} packetConn = &hysteria.PacketConnWrapper{PacketConn: packetConn}
quicConn, err := quic.Dial(packetConn, udpConn.RemoteAddr(), h.serverAddr.AddrString(), h.tlsConfig, h.quicConfig) quicConn, err := quic.Dial(h.ctx, packetConn, udpConn.RemoteAddr(), h.tlsConfig, h.quicConfig)
if err != nil { if err != nil {
packetConn.Close() packetConn.Close()
return nil, err return nil, err
@@ -267,12 +268,14 @@ func (h *Hysteria) open(ctx context.Context, reconnect bool) (quic.Connection, q
if nErr, ok := err.(net.Error); ok && !nErr.Temporary() && reconnect { if nErr, ok := err.(net.Error); ok && !nErr.Temporary() && reconnect {
return h.open(ctx, false) return h.open(ctx, false)
} }
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 { if nErr, ok := err.(net.Error); ok && !nErr.Temporary() && reconnect {
return h.open(ctx, false) return h.open(ctx, false)
} }
return nil, nil, err
} }
return conn, &hysteria.StreamWrapper{Stream: stream}, nil return conn, &hysteria.StreamWrapper{Stream: stream}, nil
} }

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

@@ -18,6 +18,7 @@ import (
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"
"github.com/sagernet/sing/service"
) )
var ( var (
@@ -39,10 +40,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,
@@ -73,7 +75,11 @@ func (s *URLTest) Start() error {
outbounds = append(outbounds, detour) outbounds = append(outbounds, detour)
} }
s.group = NewURLTestGroup(s.ctx, s.router, s.logger, outbounds, s.link, s.interval, s.tolerance) s.group = NewURLTestGroup(s.ctx, s.router, s.logger, outbounds, s.link, s.interval, s.tolerance)
go s.group.CheckOutbounds(false) return nil
}
func (s *URLTest) PostStart() error {
go s.CheckOutbounds()
return nil return nil
} }
@@ -95,6 +101,10 @@ func (s *URLTest) URLTest(ctx context.Context, link string) (map[string]uint16,
return s.group.URLTest(ctx, link) return s.group.URLTest(ctx, link)
} }
func (s *URLTest) CheckOutbounds() {
s.group.CheckOutbounds(true)
}
func (s *URLTest) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { func (s *URLTest) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
s.group.Start() s.group.Start()
outbound := s.group.Select(network) outbound := s.group.Select(network)
@@ -156,7 +166,8 @@ func NewURLTestGroup(ctx context.Context, router adapter.Router, logger log.Logg
tolerance = 50 tolerance = 50
} }
var history *urltest.HistoryStorage var history *urltest.HistoryStorage
if clashServer := router.ClashServer(); clashServer != nil { if history = service.PtrFromContext[urltest.HistoryStorage](ctx); history != nil {
} else if clashServer := router.ClashServer(); clashServer != nil {
history = clashServer.HistoryStorage() history = clashServer.HistoryStorage()
} else { } else {
history = urltest.NewHistoryStorage() history = urltest.NewHistoryStorage()

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

@@ -40,11 +40,12 @@ type WireGuard struct {
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

View File

@@ -252,7 +252,7 @@ func NewRouter(
if fakeIPOptions.Inet6Range != nil { if fakeIPOptions.Inet6Range != nil {
inet6Range = fakeIPOptions.Inet6Range.Build() inet6Range = fakeIPOptions.Inet6Range.Build()
} }
router.fakeIPStore = fakeip.NewStore(router, inet4Range, inet6Range) router.fakeIPStore = fakeip.NewStore(router, router.logger, inet4Range, inet6Range)
} }
usePlatformDefaultInterfaceMonitor := platformInterface != nil && platformInterface.UsePlatformDefaultInterfaceMonitor() usePlatformDefaultInterfaceMonitor := platformInterface != nil && platformInterface.UsePlatformDefaultInterfaceMonitor()

View File

@@ -52,13 +52,15 @@ func (r *Router) prepareGeoIPDatabase() error {
geoPath = foundPath geoPath = foundPath
} }
} }
geoPath = filemanager.BasePath(r.ctx, geoPath) if !rw.FileExists(geoPath) {
if rw.FileExists(geoPath) { geoPath = filemanager.BasePath(r.ctx, geoPath)
geoReader, codes, err := geoip.Open(geoPath) }
if err == nil { if stat, err := os.Stat(geoPath); err == nil {
r.logger.Info("loaded geoip database: ", len(codes), " codes") if stat.IsDir() {
r.geoIPReader = geoReader return E.New("geoip path is a directory: ", geoPath)
return nil }
if stat.Size() == 0 {
os.Remove(geoPath)
} }
} }
if !rw.FileExists(geoPath) { if !rw.FileExists(geoPath) {
@@ -96,7 +98,17 @@ func (r *Router) prepareGeositeDatabase() error {
geoPath = foundPath geoPath = foundPath
} }
} }
geoPath = filemanager.BasePath(r.ctx, geoPath) if !rw.FileExists(geoPath) {
geoPath = filemanager.BasePath(r.ctx, geoPath)
}
if stat, err := os.Stat(geoPath); err == nil {
if stat.IsDir() {
return E.New("geoip path is a directory: ", geoPath)
}
if stat.Size() == 0 {
os.Remove(geoPath)
}
}
if !rw.FileExists(geoPath) { if !rw.FileExists(geoPath) {
r.logger.Warn("geosite database not exists: ", geoPath) r.logger.Warn("geosite database not exists: ", geoPath)
var err error var err error
@@ -107,7 +119,6 @@ func (r *Router) prepareGeositeDatabase() error {
} }
r.logger.Error("download geosite database: ", err) r.logger.Error("download geosite database: ", err)
os.Remove(geoPath) os.Remove(geoPath)
// time.Sleep(10 * time.Second)
} }
if err != nil { if err != nil {
return err return err

View File

@@ -7,6 +7,7 @@ import (
"time" "time"
"github.com/sagernet/sing-box" "github.com/sagernet/sing-box"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common/bufio" "github.com/sagernet/sing/common/bufio"
"github.com/sagernet/sing/common/debug" "github.com/sagernet/sing/common/debug"
@@ -105,9 +106,13 @@ func testSuitSimple1(t *testing.T, clientPort uint16, testPort uint16) {
return dialer.ListenPacket(context.Background(), M.ParseSocksaddrHostPort("127.0.0.1", testPort)) return dialer.ListenPacket(context.Background(), M.ParseSocksaddrHostPort("127.0.0.1", testPort))
} }
require.NoError(t, testPingPongWithConn(t, testPort, dialTCP)) require.NoError(t, testPingPongWithConn(t, testPort, dialTCP))
require.NoError(t, testPingPongWithPacketConn(t, testPort, dialUDP)) if !C.IsDarwin {
require.NoError(t, testPingPongWithPacketConn(t, testPort, dialUDP))
}
require.NoError(t, testPingPongWithConn(t, testPort, dialTCP)) require.NoError(t, testPingPongWithConn(t, testPort, dialTCP))
require.NoError(t, testLargeDataWithPacketConn(t, testPort, dialUDP)) if !C.IsDarwin {
require.NoError(t, testLargeDataWithPacketConn(t, testPort, dialUDP))
}
} }
func testSuitWg(t *testing.T, clientPort uint16, testPort uint16) { func testSuitWg(t *testing.T, clientPort uint16, testPort uint16) {

View File

@@ -8,7 +8,8 @@ import (
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
) )
func TestProxyProtocol(t *testing.T) { // Since this is a feature one-off added by outsiders, I won't address these anymore.
func _TestProxyProtocol(t *testing.T) {
startInstance(t, option.Options{ startInstance(t, option.Options{
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
@@ -38,7 +39,7 @@ func TestProxyProtocol(t *testing.T) {
}, },
{ {
Type: C.TypeDirect, Type: C.TypeDirect,
Tag: "trojan-out", Tag: "proxy-out",
DirectOptions: option.DirectOutboundOptions{ DirectOptions: option.DirectOutboundOptions{
OverrideAddress: "127.0.0.1", OverrideAddress: "127.0.0.1",
OverridePort: serverPort, OverridePort: serverPort,
@@ -51,7 +52,7 @@ func TestProxyProtocol(t *testing.T) {
{ {
DefaultOptions: option.DefaultRule{ DefaultOptions: option.DefaultRule{
Inbound: []string{"mixed-in"}, Inbound: []string{"mixed-in"},
Outbound: "trojan-out", Outbound: "proxy-out",
}, },
}, },
}, },

View File

@@ -7,7 +7,6 @@ import (
"testing" "testing"
"time" "time"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing/common/debug" "github.com/sagernet/sing/common/debug"
F "github.com/sagernet/sing/common/format" F "github.com/sagernet/sing/common/format"
"github.com/sagernet/sing/common/rw" "github.com/sagernet/sing/common/rw"
@@ -54,9 +53,7 @@ func startDockerContainer(t *testing.T, options DockerOptions) {
containerOptions.ExposedPorts = make(nat.PortSet) containerOptions.ExposedPorts = make(nat.PortSet)
var hostOptions container.HostConfig var hostOptions container.HostConfig
if !C.IsDarwin { hostOptions.NetworkMode = "host"
hostOptions.NetworkMode = "host"
}
hostOptions.CapAdd = options.Cap hostOptions.CapAdd = options.Cap
hostOptions.PortBindings = make(nat.PortMap) hostOptions.PortBindings = make(nat.PortMap)

View File

@@ -10,21 +10,23 @@ 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.4 github.com/sagernet/sing v0.2.8-0.20230707055657-7c9b4d624da7
github.com/sagernet/sing-shadowsocks v0.2.2-0.20230417102954-f77257340507 github.com/sagernet/sing-shadowsocks v0.2.3-0.20230703131347-b044960bd355
github.com/sagernet/sing-shadowsocks2 v0.1.2-0.20230703131506-ca0c6adde968
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.4
go.uber.org/goleak v1.2.0 go.uber.org/goleak v1.2.0
golang.org/x/net v0.9.0 golang.org/x/net v0.12.0
) )
require ( require (
berty.tech/go-libtor v1.0.385 // indirect berty.tech/go-libtor v1.0.385 // indirect
github.com/Dreamacro/clash v1.15.0 // indirect github.com/Dreamacro/clash v1.17.0 // indirect
github.com/Dreamacro/protobytes v0.0.0-20230617041236-6500a9f4f158 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect github.com/Microsoft/go-winio v0.6.0 // 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/caddyserver/certmagic v0.17.2 // indirect github.com/caddyserver/certmagic v0.18.2 // indirect
github.com/cloudflare/circl v1.2.1-0.20221019164342-6ab4dfed8f3c // indirect github.com/cloudflare/circl v1.2.1-0.20221019164342-6ab4dfed8f3c // indirect
github.com/cretz/bine v0.2.0 // indirect github.com/cretz/bine v0.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
@@ -35,69 +37,72 @@ require (
github.com/go-chi/chi/v5 v5.0.8 // indirect github.com/go-chi/chi/v5 v5.0.8 // indirect
github.com/go-chi/cors v1.2.1 // indirect github.com/go-chi/cors v1.2.1 // indirect
github.com/go-chi/render v1.0.2 // indirect github.com/go-chi/render v1.0.2 // 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/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/protobuf v1.5.2 // indirect github.com/google/btree v1.1.2 // indirect
github.com/google/btree v1.0.1 // 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/insomniacslk/dhcp v0.0.0-20230407062729-974c6f05fe16 // indirect github.com/insomniacslk/dhcp v0.0.0-20230612134759-b20c9ba983df // 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.5 // indirect
github.com/libdns/libdns v0.2.1 // indirect github.com/libdns/libdns v0.2.1 // indirect
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
github.com/mholt/acmez v1.1.0 // indirect github.com/mholt/acmez v1.2.0 // indirect
github.com/miekg/dns v1.1.53 // indirect github.com/miekg/dns v1.1.55 // indirect
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
github.com/morikuni/aec v1.0.0 // indirect github.com/morikuni/aec v1.0.0 // indirect
github.com/onsi/ginkgo/v2 v2.2.0 // indirect github.com/onsi/ginkgo/v2 v2.2.0 // indirect
github.com/ooni/go-libtor v1.1.7 // indirect github.com/ooni/go-libtor v1.1.8 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/oschwald/maxminddb-golang v1.10.0 // indirect github.com/oschwald/maxminddb-golang v1.11.0 // indirect
github.com/pierrec/lz4/v4 v4.1.14 // indirect github.com/pierrec/lz4/v4 v4.1.14 // indirect
github.com/pires/go-proxyproto v0.7.0 // indirect github.com/pires/go-proxyproto v0.7.0 // indirect
github.com/pkg/errors v0.9.1 // 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
github.com/quic-go/qtls-go1-19 v0.2.0 // indirect github.com/quic-go/qtls-go1-19 v0.3.2 // indirect
github.com/quic-go/qtls-go1-20 v0.1.0 // indirect github.com/quic-go/qtls-go1-20 v0.2.2 // indirect
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0 // indirect github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0 // indirect
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect
github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2 // indirect
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 // indirect github.com/sagernet/quic-go v0.0.0-20230615020047-10f05c797c02 // 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.7-0.20230703131656-fd65b6178bf9 // indirect
github.com/sagernet/sing-shadowtls v0.1.2-0.20230417103049-4f682e05f19b // indirect github.com/sagernet/sing-mux v0.1.1-0.20230703132253-2cedde0fbc90 // indirect
github.com/sagernet/sing-tun v0.1.5-0.20230422121432-209ec123ca7b // indirect github.com/sagernet/sing-shadowtls v0.1.3-0.20230703132509-93bbad3057e4 // indirect
github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3 // indirect github.com/sagernet/sing-tun v0.1.9-0.20230703134424-fd850d00e5cd // indirect
github.com/sagernet/sing-vmess v0.1.7-0.20230711074224-7d2a9a318162 // indirect
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 // indirect github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 // indirect
github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 // indirect github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 // indirect
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 // indirect github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 // indirect
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e // indirect github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e // indirect
github.com/sagernet/wireguard-go v0.0.0-20230420044414-a7bac1754e77 // indirect github.com/sagernet/wireguard-go v0.0.0-20230420044414-a7bac1754e77 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 // indirect
github.com/sirupsen/logrus v1.9.3 // 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.etcd.io/bbolt v1.3.7 // indirect go.etcd.io/bbolt v1.3.7 // 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
go.uber.org/zap v1.24.0 // indirect go.uber.org/zap v1.24.0 // indirect
go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 // indirect go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 // indirect
golang.org/x/crypto v0.8.0 // indirect golang.org/x/crypto v0.11.0 // indirect
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect
golang.org/x/mod v0.8.0 // indirect golang.org/x/mod v0.11.0 // indirect
golang.org/x/sys v0.7.0 // indirect golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.9.0 // indirect golang.org/x/text v0.11.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.10.0 // indirect
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
google.golang.org/grpc v1.54.0 // indirect google.golang.org/grpc v1.56.2 // indirect
google.golang.org/protobuf v1.30.0 // indirect google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
gvisor.dev/gvisor v0.0.0-20230415003630-3981d5d5e523 // indirect gotest.tools/v3 v3.4.0 // indirect
lukechampine.com/blake3 v1.1.7 // indirect lukechampine.com/blake3 v1.2.1 // indirect
) )

View File

@@ -1,8 +1,10 @@
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/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Dreamacro/clash v1.15.0 h1:mlpD950VEggXZBNahV66hyKDRxcczkj3vymoAt78KyE= github.com/Dreamacro/clash v1.17.0 h1:LWtp6KcnrCiujY58ufI8pylI+hbCBgSCsLI90EWhpi4=
github.com/Dreamacro/clash v1.15.0/go.mod h1:WNH69bN11LiAdgdSr4hpkEuXVMfBbWyhEKMCTx9BtNE= github.com/Dreamacro/clash v1.17.0/go.mod h1:PtcAft7sdsK325BD6uwm8wvhOkMV3TCeED6dfZ/lnfE=
github.com/Dreamacro/protobytes v0.0.0-20230617041236-6500a9f4f158 h1:JFnwKplz9hj8ubqYjm8HkgZS1Rvz9yW+u/XCNNTxr0k=
github.com/Dreamacro/protobytes v0.0.0-20230617041236-6500a9f4f158/go.mod h1:QvmEZ/h6KXszPOr2wUFl7Zn3hfFNYdfbXwPVDTyZs6k=
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
@@ -10,8 +12,8 @@ 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.2 h1:Nj2+M+A2Ho9IF6n1wUSbra4mX1X6ALzWpul9HooprHA=
github.com/caddyserver/certmagic v0.17.2/go.mod h1:ouWUuC490GOLJzkyN35eXfV8bSbwMwSf4bdhkIxtdQE= github.com/caddyserver/certmagic v0.18.2/go.mod h1:cLsgYXecH1iVUPjDXw15/1SKjZk/TK+aFfQk5FnugGQ=
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=
@@ -41,6 +43,8 @@ github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-chi/render v1.0.2 h1:4ER/udB0+fMWB2Jlf15RV3F4A2FDuYi/9f+lFttR/Lg= github.com/go-chi/render v1.0.2 h1:4ER/udB0+fMWB2Jlf15RV3F4A2FDuYi/9f+lFttR/Lg=
github.com/go-chi/render v1.0.2/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0= github.com/go-chi/render v1.0.2/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M= github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
@@ -48,12 +52,11 @@ github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
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/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=
@@ -61,8 +64,8 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
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/insomniacslk/dhcp v0.0.0-20230407062729-974c6f05fe16 h1:+aAGyK41KRn8jbF2Q7PLL0Sxwg6dShGcQSeCC7nZQ8E= github.com/insomniacslk/dhcp v0.0.0-20230612134759-b20c9ba983df h1:pF1MMIzEJzJ/MyI4bXYXVYyN8CJgoQ2PPKT2z3O/Cl4=
github.com/insomniacslk/dhcp v0.0.0-20230407062729-974c6f05fe16/go.mod h1:IKrnDWs3/Mqq5n0lI+RxA2sB7MvN/vbMBP3ehXg65UI= github.com/insomniacslk/dhcp v0.0.0-20230612134759-b20c9ba983df/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=
@@ -70,18 +73,17 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
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.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
github.com/klauspost/cpuid/v2 v2.1.1 h1:t0wUqjowdm8ezddV5k0tLWVklVuvLJpoHeb4WBdydm0= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis= 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.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
github.com/mholt/acmez v1.1.0/go.mod h1:zwo5+fbLLTowAX8o8ETfQzbDtwGEXnPhkmGdKIP+bgs= github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo=
github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA=
github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
@@ -90,14 +92,14 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb
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/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/oschwald/maxminddb-golang v1.10.0 h1:Xp1u0ZhqkSuopaKmk1WwHtjF0H9Hd9181uj2MQ5Vndg= github.com/oschwald/maxminddb-golang v1.11.0 h1:aSXMqYR/EPNjGE8epgqwDay+P30hCBZIveY0WZbAWh0=
github.com/oschwald/maxminddb-golang v1.10.0/go.mod h1:Y2ELenReaLAZ0b400URyGwvYxHV1dLIxBuyOsyYjHK0= github.com/oschwald/maxminddb-golang v1.11.0/go.mod h1:YmVI+H0zh3ySFR3w+oz8PCfglAFj3PuCmui13+P9zDg=
github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE= github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE=
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs= github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
@@ -110,34 +112,40 @@ github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
github.com/quic-go/qtls-go1-18 v0.2.0 h1:5ViXqBZ90wpUcZS0ge79rf029yx0dYB0McyPJwqqj7U= github.com/quic-go/qtls-go1-18 v0.2.0 h1:5ViXqBZ90wpUcZS0ge79rf029yx0dYB0McyPJwqqj7U=
github.com/quic-go/qtls-go1-18 v0.2.0/go.mod h1:moGulGHK7o6O8lSPSZNoOwcLvJKJ85vVNc7oJFD65bc= github.com/quic-go/qtls-go1-18 v0.2.0/go.mod h1:moGulGHK7o6O8lSPSZNoOwcLvJKJ85vVNc7oJFD65bc=
github.com/quic-go/qtls-go1-19 v0.2.0 h1:Cvn2WdhyViFUHoOqK52i51k4nDX8EwIh5VJiVM4nttk= github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U=
github.com/quic-go/qtls-go1-19 v0.2.0/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI=
github.com/quic-go/qtls-go1-20 v0.1.0 h1:d1PK3ErFy9t7zxKsG3NXBJXZjp/kMLoIb3y/kV54oAI= github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E=
github.com/quic-go/qtls-go1-20 v0.1.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0 h1:KyhtFFt1Jtp5vW2ohNvstvQffTOQ/s5vENuGXzdA+TM= github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0 h1:KyhtFFt1Jtp5vW2ohNvstvQffTOQ/s5vENuGXzdA+TM=
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0/go.mod h1:D4SFEOkJK+4W1v86ZhX0jPM0rAL498fyQAChqMtes/I= github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0/go.mod h1:D4SFEOkJK+4W1v86ZhX0jPM0rAL498fyQAChqMtes/I=
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA= github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA=
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/gvisor v0.0.0-20230627031050-1ab0276e0dd2 h1:dnkKrzapqtAwjTSWt6hdPrARORfoYvuUczynvRLrueo=
github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2/go.mod h1:1JUiV7nGuf++YFm9eWZ8q2lrwHmhcUGzptMl/vL1+LA=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE= github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 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-20230615020047-10f05c797c02 h1:9S+L1n/4hbe1pCLNTZnnddSNseQda8tuSm/+uRy6p8s=
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32/go.mod h1:QMCkxXAC3CvBgDZVIJp43NWTuwGBScCzMLVLynjERL8= github.com/sagernet/quic-go v0.0.0-20230615020047-10f05c797c02/go.mod h1:rth94YcHJfkC4mG03JTXmv7mJsDc8MOIIqQrCtoaV4U=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
github.com/sagernet/sing v0.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.4 h1:gC8BR5sglbJZX23RtMyFa8EETP9YEUADhfbEzU1yVbo= github.com/sagernet/sing v0.2.8-0.20230707055657-7c9b4d624da7 h1:sKQu4Gc6vMfzleoFK3h8ROfn/TP2U36qQME3/iYaoqA=
github.com/sagernet/sing v0.2.4/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= github.com/sagernet/sing v0.2.8-0.20230707055657-7c9b4d624da7/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.7-0.20230703131656-fd65b6178bf9 h1:35qe74ygIKj5uQkDDD0Xtv+iWOspQsS/Lqhs2XiY0Ak=
github.com/sagernet/sing-dns v0.1.5-0.20230415085626-111ecf799dfc/go.mod h1:ZKuuqgsHRxDahYrzgSgy4vIAGGuKPlIf4hLcNzYzLkY= github.com/sagernet/sing-dns v0.1.7-0.20230703131656-fd65b6178bf9/go.mod h1:wgmbh0yruJXRO8tmfwPx6hOl6pyReWRoeHdkRehWkmw=
github.com/sagernet/sing-shadowsocks v0.2.2-0.20230417102954-f77257340507 h1:bAHZCdWqJkb8LEW98+YsMVDXGRMUVjka8IC+St6ot88= github.com/sagernet/sing-mux v0.1.1-0.20230703132253-2cedde0fbc90 h1:aEe2HrRc9OTS7IZ8RHyh224OhltnwRQs4/y89UsHPo8=
github.com/sagernet/sing-shadowsocks v0.2.2-0.20230417102954-f77257340507/go.mod h1:UJjvQGw0lyYaDGIDvUraL16fwaAEH1WFw1Y6sUcMPog= github.com/sagernet/sing-mux v0.1.1-0.20230703132253-2cedde0fbc90/go.mod h1:sm126rB5EUi9HLf4jCSHTqo+XRPbh4BoEVeLbr2WRbE=
github.com/sagernet/sing-shadowtls v0.1.2-0.20230417103049-4f682e05f19b h1:ouW/6IDCrxkBe19YSbdCd7buHix7b+UZ6BM4Zz74XF4= github.com/sagernet/sing-shadowsocks v0.2.3-0.20230703131347-b044960bd355 h1:XOgNZYnkDrx5qtNS4kqIOHMhjZuc7mJ2pY/x3EyZX8Q=
github.com/sagernet/sing-shadowtls v0.1.2-0.20230417103049-4f682e05f19b/go.mod h1:oG8bPerYI6cZ74KquY3DvA7ynECyrILPBnce6wtBqeI= github.com/sagernet/sing-shadowsocks v0.2.3-0.20230703131347-b044960bd355/go.mod h1:atEATsxqPo8qCPcFt8Rw7TFEJ70egCoMR7PziX4jmjI=
github.com/sagernet/sing-tun v0.1.5-0.20230422121432-209ec123ca7b h1:9NsciSJGwzdkXwVvT2c2g+RvkTVkANeBLr2l+soJ7LM= github.com/sagernet/sing-shadowsocks2 v0.1.2-0.20230703131506-ca0c6adde968 h1:UctXygnZfqsFR+2hZXfpWK3pSYKLbBQMuli9GDE6QU0=
github.com/sagernet/sing-tun v0.1.5-0.20230422121432-209ec123ca7b/go.mod h1:DD7Ce2Gt0GFc6I/1+Uw4D/aUlBsGqrQsC52CMK/V818= github.com/sagernet/sing-shadowsocks2 v0.1.2-0.20230703131506-ca0c6adde968/go.mod h1:xFxUGbtnqRLxtQftCILFeKf43GE6S83f0I6CsO9BxGE=
github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3 h1:BHOnxrbC929JonuKqFdJ7ZbDp7zs4oTlH5KFvKtWu9U= github.com/sagernet/sing-shadowtls v0.1.3-0.20230703132509-93bbad3057e4 h1:ZjLyCkEENqXzGp4PRZbQGk5wPzEq0Rg+/2jK82lmy3Q=
github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3/go.mod h1:yKrAr+dqZd64DxBXCHWrYicp+n4qbqO73mtwv3dck8U= github.com/sagernet/sing-shadowtls v0.1.3-0.20230703132509-93bbad3057e4/go.mod h1:8ZSSHJSNOG7cUCUYJemZNH873EsKdFqABykTypoS/2M=
github.com/sagernet/sing-tun v0.1.9-0.20230703134424-fd850d00e5cd h1:lkJA/P1L2XE5lNDnzA2fygx6DZIks3Sx87GN2OE0jNY=
github.com/sagernet/sing-tun v0.1.9-0.20230703134424-fd850d00e5cd/go.mod h1:XNQoXtvsmeva+dADmo/57KktLNgm5ubOyR67Niahqj8=
github.com/sagernet/sing-vmess v0.1.7-0.20230711074224-7d2a9a318162 h1:EvEbqAdZJalFqLwKSHIixH+TRed0iY2f8KatI7mtt1Q=
github.com/sagernet/sing-vmess v0.1.7-0.20230711074224-7d2a9a318162/go.mod h1:FHEBboQRvfBDbZd/fAKBpgR4w7QbYyzNL/MLd22/iTk=
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=
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37/go.mod h1:3skNSftZDJWTGVtVaM2jfbce8qHnmH/AGDRe62iNOg0= github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37/go.mod h1:3skNSftZDJWTGVtVaM2jfbce8qHnmH/AGDRe62iNOg0=
github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 h1:2ItpW1nMNkPzmBTxV0/eClCklHrFSQMnUGcpUmJxVeE= github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 h1:2ItpW1nMNkPzmBTxV0/eClCklHrFSQMnUGcpUmJxVeE=
@@ -148,36 +156,32 @@ github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e h1:7uw2njHFGE+V
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e/go.mod h1:45TUl8+gH4SIKr4ykREbxKWTxkDlSzFENzctB1dVRRY= github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e/go.mod h1:45TUl8+gH4SIKr4ykREbxKWTxkDlSzFENzctB1dVRRY=
github.com/sagernet/wireguard-go v0.0.0-20230420044414-a7bac1754e77 h1:g6QtRWQ2dKX7EQP++1JLNtw4C2TNxd4/ov8YUpOPOSo= github.com/sagernet/wireguard-go v0.0.0-20230420044414-a7bac1754e77 h1:g6QtRWQ2dKX7EQP++1JLNtw4C2TNxd4/ov8YUpOPOSo=
github.com/sagernet/wireguard-go v0.0.0-20230420044414-a7bac1754e77/go.mod h1:pJDdXzZIwJ+2vmnT0TKzmf8meeum+e2mTDSehw79eE0= github.com/sagernet/wireguard-go v0.0.0-20230420044414-a7bac1754e77/go.mod h1:pJDdXzZIwJ+2vmnT0TKzmf8meeum+e2mTDSehw79eE0=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 h1:rc/CcqLH3lh8n+csdOuDfP+NuykE0U6AeYSJJHKDgSg=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9/go.mod h1:a/83NAfUXvEuLpmxDssAXxgUgrEy12MId3Wd7OTs76s=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spyzhov/ajson v0.7.1 h1:1MDIlPc6x0zjNtpa7tDzRAyFAvRX+X8ZsvtYz5lZg6A= github.com/spyzhov/ajson v0.7.1 h1:1MDIlPc6x0zjNtpa7tDzRAyFAvRX+X8ZsvtYz5lZg6A=
github.com/spyzhov/ajson v0.7.1/go.mod h1:63V+CGM6f1Bu/p4nLIN8885ojBdt88TbLoSFzyqMuVA= github.com/spyzhov/ajson v0.7.1/go.mod h1:63V+CGM6f1Bu/p4nLIN8885ojBdt88TbLoSFzyqMuVA=
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=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
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.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
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=
@@ -187,76 +191,72 @@ golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaE
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-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
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.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME=
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.8.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-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
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-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.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
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=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-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.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.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.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
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.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
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.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
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=
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI=
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -264,7 +264,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
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=
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
gvisor.dev/gvisor v0.0.0-20230415003630-3981d5d5e523 h1:zUQYeyyPLnSR6yMvLSOmLH37xDWCZ7BqlpE69fE5K3Q= gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g=
gvisor.dev/gvisor v0.0.0-20230415003630-3981d5d5e523/go.mod h1:pzr6sy8gDLfVmDAg8OYrlKvGEHw5C3PGTiBXBTCx76Q= lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA=

View File

@@ -125,7 +125,7 @@ func TestHysteriaOutbound(t *testing.T) {
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org") _, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
startDockerContainer(t, DockerOptions{ startDockerContainer(t, DockerOptions{
Image: ImageHysteria, Image: ImageHysteria,
Ports: []uint16{serverPort, testPort}, Ports: []uint16{testPort},
Cmd: []string{"-c", "/etc/hysteria/config.json", "server"}, Cmd: []string{"-c", "/etc/hysteria/config.json", "server"},
Bind: map[string]string{ Bind: map[string]string{
"hysteria-server.json": "/etc/hysteria/config.json", "hysteria-server.json": "/etc/hysteria/config.json",

View File

@@ -32,6 +32,7 @@ func TestMuxCoolServer(t *testing.T) {
Image: ImageV2RayCore, Image: ImageV2RayCore,
Ports: []uint16{serverPort, testPort}, Ports: []uint16{serverPort, testPort},
EntryPoint: "v2ray", EntryPoint: "v2ray",
Cmd: []string{"run"},
Stdin: content, Stdin: content,
}) })

View File

@@ -4,7 +4,6 @@ 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"
@@ -12,24 +11,25 @@ import (
"github.com/gofrs/uuid/v5" "github.com/gofrs/uuid/v5"
) )
var muxProtocols = []mux.Protocol{ var muxProtocols = []string{
mux.ProtocolYAMux, "h2mux",
mux.ProtocolSMux, "smux",
"yamux",
} }
func TestVMessSMux(t *testing.T) { func TestVMessSMux(t *testing.T) {
testVMessMux(t, option.MultiplexOptions{ testVMessMux(t, option.MultiplexOptions{
Enabled: true, Enabled: true,
Protocol: mux.ProtocolSMux.String(), Protocol: "smux",
}) })
} }
func TestShadowsocksMux(t *testing.T) { func TestShadowsocksMux(t *testing.T) {
for _, protocol := range muxProtocols { for _, protocol := range muxProtocols {
t.Run(protocol.String(), func(t *testing.T) { t.Run(protocol, func(t *testing.T) {
testShadowsocksMux(t, option.MultiplexOptions{ testShadowsocksMux(t, option.MultiplexOptions{
Enabled: true, Enabled: true,
Protocol: protocol.String(), Protocol: protocol,
}) })
}) })
} }
@@ -38,7 +38,7 @@ func TestShadowsocksMux(t *testing.T) {
func TestShadowsockH2Mux(t *testing.T) { func TestShadowsockH2Mux(t *testing.T) {
testShadowsocksMux(t, option.MultiplexOptions{ testShadowsocksMux(t, option.MultiplexOptions{
Enabled: true, Enabled: true,
Protocol: mux.ProtocolH2Mux.String(), Protocol: "h2mux",
Padding: true, Padding: true,
}) })
} }
@@ -46,7 +46,7 @@ func TestShadowsockH2Mux(t *testing.T) {
func TestShadowsockSMuxPadding(t *testing.T) { func TestShadowsockSMuxPadding(t *testing.T) {
testShadowsocksMux(t, option.MultiplexOptions{ testShadowsocksMux(t, option.MultiplexOptions{
Enabled: true, Enabled: true,
Protocol: mux.ProtocolSMux.String(), Protocol: "smux",
Padding: true, Padding: true,
}) })
} }

View File

@@ -143,8 +143,10 @@ func TestShadowTLSFallback(t *testing.T) {
ServerPort: 443, ServerPort: 443,
}, },
}, },
Version: 3, Version: 3,
Password: "hello", Users: []option.ShadowTLSUser{
{Password: "hello"},
},
}, },
}, },
}, },
@@ -199,8 +201,10 @@ func TestShadowTLSInbound(t *testing.T) {
ServerPort: 443, ServerPort: 443,
}, },
}, },
Version: 3, Version: 3,
Password: password, Users: []option.ShadowTLSUser{
{Password: password},
},
}, },
}, },
{ {

View File

@@ -18,7 +18,8 @@ func TestShadowsocksObfs(t *testing.T) {
} }
} }
func TestShadowsocksV2RayPlugin(t *testing.T) { // Since I can't test this on m1 mac (rosetta error: bss_size overflow), I don't care about it
func _TestShadowsocksV2RayPlugin(t *testing.T) {
testShadowsocksPlugin(t, "v2ray-plugin", "", "--plugin v2ray-plugin --plugin-opts=server") testShadowsocksPlugin(t, "v2ray-plugin", "", "--plugin v2ray-plugin --plugin-opts=server")
} }

View File

@@ -1,59 +0,0 @@
package main
import (
"context"
"net"
"testing"
"time"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/buf"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/udpnat"
)
func TestUDPNatClose(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
connCtx, connCancel := common.ContextWithCancelCause(context.Background())
defer connCancel(net.ErrClosed)
service := udpnat.New[int](1, &testUDPNatCloseHandler{connCancel})
service.NewPacket(ctx, 0, buf.As([]byte("Hello")), M.Metadata{}, func(natConn N.PacketConn) N.PacketWriter {
return &testPacketWriter{}
})
select {
case <-connCtx.Done():
if E.IsClosed(connCtx.Err()) {
t.Fatal(E.New("conn closed unexpectedly: ", connCtx.Err()))
}
case <-time.After(2 * time.Second):
t.Fatal("conn not closed")
}
}
type testUDPNatCloseHandler struct {
done common.ContextCancelCauseFunc
}
func (h *testUDPNatCloseHandler) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
for {
buffer := buf.NewPacket()
_, err := conn.ReadPacket(buffer)
buffer.Release()
if err != nil {
h.done(err)
return err
}
}
}
func (h *testUDPNatCloseHandler) NewError(ctx context.Context, err error) {
}
type testPacketWriter struct{}
func (t *testPacketWriter) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
return nil
}

View File

@@ -75,6 +75,7 @@ func testV2RayGRPCInbound(t *testing.T, forceLite bool) {
Image: ImageV2RayCore, Image: ImageV2RayCore,
Ports: []uint16{serverPort, testPort}, Ports: []uint16{serverPort, testPort},
EntryPoint: "v2ray", EntryPoint: "v2ray",
Cmd: []string{"run"},
Stdin: content, Stdin: content,
Bind: map[string]string{ Bind: map[string]string{
certPem: "/path/to/certificate.crt", certPem: "/path/to/certificate.crt",
@@ -114,6 +115,7 @@ func testV2RayGRPCOutbound(t *testing.T, forceLite bool) {
Image: ImageV2RayCore, Image: ImageV2RayCore,
Ports: []uint16{serverPort, testPort}, Ports: []uint16{serverPort, testPort},
EntryPoint: "v2ray", EntryPoint: "v2ray",
Cmd: []string{"run"},
Stdin: content, Stdin: content,
Env: []string{"V2RAY_VMESS_AEAD_FORCED=false"}, Env: []string{"V2RAY_VMESS_AEAD_FORCED=false"},
Bind: map[string]string{ Bind: map[string]string{

View File

@@ -113,6 +113,7 @@ func testV2RayWebsocketInbound(t *testing.T, maxEarlyData uint32, earlyDataHeade
Image: ImageV2RayCore, Image: ImageV2RayCore,
Ports: []uint16{serverPort, testPort}, Ports: []uint16{serverPort, testPort},
EntryPoint: "v2ray", EntryPoint: "v2ray",
Cmd: []string{"run"},
Stdin: content, Stdin: content,
Bind: map[string]string{ Bind: map[string]string{
certPem: "/path/to/certificate.crt", certPem: "/path/to/certificate.crt",
@@ -146,6 +147,7 @@ func testV2RayWebsocketOutbound(t *testing.T, maxEarlyData uint32, earlyDataHead
Image: ImageV2RayCore, Image: ImageV2RayCore,
Ports: []uint16{serverPort, testPort}, Ports: []uint16{serverPort, testPort},
EntryPoint: "v2ray", EntryPoint: "v2ray",
Cmd: []string{"run"},
Stdin: content, Stdin: content,
Env: []string{"V2RAY_VMESS_AEAD_FORCED=false"}, Env: []string{"V2RAY_VMESS_AEAD_FORCED=false"},
Bind: map[string]string{ Bind: map[string]string{

View File

@@ -175,6 +175,7 @@ func testVMessInboundWithV2Ray(t *testing.T, security string, alterId int, authe
Image: ImageV2RayCore, Image: ImageV2RayCore,
Ports: []uint16{serverPort, testPort}, Ports: []uint16{serverPort, testPort},
EntryPoint: "v2ray", EntryPoint: "v2ray",
Cmd: []string{"run"},
Stdin: content, Stdin: content,
Env: []string{"V2RAY_VMESS_AEAD_FORCED=false"}, Env: []string{"V2RAY_VMESS_AEAD_FORCED=false"},
}) })
@@ -222,6 +223,7 @@ func testVMessOutboundWithV2Ray(t *testing.T, security string, globalPadding boo
Image: ImageV2RayCore, Image: ImageV2RayCore,
Ports: []uint16{serverPort, testPort}, Ports: []uint16{serverPort, testPort},
EntryPoint: "v2ray", EntryPoint: "v2ray",
Cmd: []string{"run"},
Stdin: content, Stdin: content,
Env: []string{"V2RAY_VMESS_AEAD_FORCED=false"}, Env: []string{"V2RAY_VMESS_AEAD_FORCED=false"},
}) })

View File

@@ -9,7 +9,7 @@ import (
"github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/option"
) )
func TestWireGuard(t *testing.T) { func _TestWireGuard(t *testing.T) {
startDockerContainer(t, DockerOptions{ startDockerContainer(t, DockerOptions{
Image: ImageBoringTun, Image: ImageBoringTun,
Cap: []string{"MKNOD", "NET_ADMIN", "NET_RAW"}, Cap: []string{"MKNOD", "NET_ADMIN", "NET_RAW"},

View File

@@ -199,9 +199,7 @@ func (t *Transport) fetchServers0(ctx context.Context, iface *net.Interface) err
} }
func (t *Transport) fetchServersResponse(iface *net.Interface, packetConn net.PacketConn, transactionID dhcpv4.TransactionID) error { func (t *Transport) fetchServersResponse(iface *net.Interface, packetConn net.PacketConn, transactionID dhcpv4.TransactionID) error {
_buffer := buf.StackNewSize(dhcpv4.MaxMessageSize) buffer := buf.NewSize(dhcpv4.MaxMessageSize)
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release() defer buffer.Release()
for { for {

View File

@@ -2,43 +2,78 @@ package fakeip
import ( import (
"net/netip" "net/netip"
"sync"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing/common/cache" "github.com/sagernet/sing/common/logger"
) )
var _ adapter.FakeIPStorage = (*MemoryStorage)(nil) var _ adapter.FakeIPStorage = (*MemoryStorage)(nil)
type MemoryStorage struct { type MemoryStorage struct {
metadata *adapter.FakeIPMetadata addressAccess sync.RWMutex
domainCache *cache.LruCache[netip.Addr, string] domainAccess sync.RWMutex
addressCache map[netip.Addr]string
domainCache4 map[string]netip.Addr
domainCache6 map[string]netip.Addr
} }
func NewMemoryStorage() *MemoryStorage { func NewMemoryStorage() *MemoryStorage {
return &MemoryStorage{ return &MemoryStorage{
domainCache: cache.New[netip.Addr, string](), addressCache: make(map[netip.Addr]string),
domainCache4: make(map[string]netip.Addr),
domainCache6: make(map[string]netip.Addr),
} }
} }
func (s *MemoryStorage) FakeIPMetadata() *adapter.FakeIPMetadata { func (s *MemoryStorage) FakeIPMetadata() *adapter.FakeIPMetadata {
return s.metadata return nil
} }
func (s *MemoryStorage) FakeIPSaveMetadata(metadata *adapter.FakeIPMetadata) error { func (s *MemoryStorage) FakeIPSaveMetadata(metadata *adapter.FakeIPMetadata) error {
s.metadata = metadata
return nil return nil
} }
func (s *MemoryStorage) FakeIPStore(address netip.Addr, domain string) error { func (s *MemoryStorage) FakeIPStore(address netip.Addr, domain string) error {
s.domainCache.Store(address, domain) s.addressAccess.Lock()
s.domainAccess.Lock()
s.addressCache[address] = domain
if address.Is4() {
s.domainCache4[domain] = address
} else {
s.domainCache6[domain] = address
}
s.domainAccess.Unlock()
s.addressAccess.Unlock()
return nil return nil
} }
func (s *MemoryStorage) FakeIPStoreAsync(address netip.Addr, domain string, logger logger.Logger) {
_ = s.FakeIPStore(address, domain)
}
func (s *MemoryStorage) FakeIPLoad(address netip.Addr) (string, bool) { func (s *MemoryStorage) FakeIPLoad(address netip.Addr) (string, bool) {
return s.domainCache.Load(address) s.addressAccess.RLock()
defer s.addressAccess.RUnlock()
domain, loaded := s.addressCache[address]
return domain, loaded
}
func (s *MemoryStorage) FakeIPLoadDomain(domain string, isIPv6 bool) (netip.Addr, bool) {
s.domainAccess.RLock()
defer s.domainAccess.RUnlock()
if !isIPv6 {
address, loaded := s.domainCache4[domain]
return address, loaded
} else {
address, loaded := s.domainCache6[domain]
return address, loaded
}
} }
func (s *MemoryStorage) FakeIPReset() error { func (s *MemoryStorage) FakeIPReset() error {
s.domainCache = cache.New[netip.Addr, string]() s.addressCache = make(map[netip.Addr]string)
s.domainCache4 = make(map[string]netip.Addr)
s.domainCache6 = make(map[string]netip.Addr)
return nil return nil
} }

View File

@@ -69,14 +69,14 @@ func (s *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg,
func (s *Transport) 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, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
addresses = append(addresses, inet4Address) addresses = append(addresses, inet4Address)
} }
if strategy != dns.DomainStrategyUseIPv4 { if strategy != dns.DomainStrategyUseIPv4 {
inet6Address, err := s.store.Create(domain, dns.DomainStrategyUseIPv6) inet6Address, err := s.store.Create(domain, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -4,14 +4,15 @@ import (
"net/netip" "net/netip"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-dns"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
) )
var _ adapter.FakeIPStore = (*Store)(nil) var _ adapter.FakeIPStore = (*Store)(nil)
type Store struct { type Store struct {
router adapter.Router router adapter.Router
logger logger.Logger
inet4Range netip.Prefix inet4Range netip.Prefix
inet6Range netip.Prefix inet6Range netip.Prefix
storage adapter.FakeIPStorage storage adapter.FakeIPStorage
@@ -19,9 +20,10 @@ type Store struct {
inet6Current netip.Addr inet6Current netip.Addr
} }
func NewStore(router adapter.Router, inet4Range netip.Prefix, inet6Range netip.Prefix) *Store { func NewStore(router adapter.Router, logger logger.Logger, inet4Range netip.Prefix, inet6Range netip.Prefix) *Store {
return &Store{ return &Store{
router: router, router: router,
logger: logger,
inet4Range: inet4Range, inet4Range: inet4Range,
inet6Range: inet6Range, inet6Range: inet6Range,
} }
@@ -48,6 +50,7 @@ func (s *Store) Start() error {
if s.inet6Range.IsValid() { if s.inet6Range.IsValid() {
s.inet6Current = s.inet6Range.Addr().Next().Next() s.inet6Current = s.inet6Range.Addr().Next().Next()
} }
_ = storage.FakeIPReset()
} }
s.storage = storage s.storage = storage
return nil return nil
@@ -69,9 +72,12 @@ func (s *Store) Close() error {
}) })
} }
func (s *Store) Create(domain string, strategy dns.DomainStrategy) (netip.Addr, error) { func (s *Store) Create(domain string, isIPv6 bool) (netip.Addr, error) {
if address, loaded := s.storage.FakeIPLoadDomain(domain, isIPv6); loaded {
return address, nil
}
var address netip.Addr var address netip.Addr
if strategy == dns.DomainStrategyUseIPv4 { if !isIPv6 {
if !s.inet4Current.IsValid() { if !s.inet4Current.IsValid() {
return netip.Addr{}, E.New("missing IPv4 fakeip address range") return netip.Addr{}, E.New("missing IPv4 fakeip address range")
} }
@@ -92,10 +98,7 @@ func (s *Store) Create(domain string, strategy dns.DomainStrategy) (netip.Addr,
s.inet6Current = nextAddress s.inet6Current = nextAddress
address = nextAddress address = nextAddress
} }
err := s.storage.FakeIPStore(address, domain) s.storage.FakeIPStoreAsync(address, domain, s.logger)
if err != nil {
return netip.Addr{}, err
}
return address, nil return address, nil
} }

View File

@@ -41,9 +41,7 @@ func WriteClientHello(stream io.Writer, hello ClientHello) error {
requestLen += 8 // recvBPS requestLen += 8 // recvBPS
requestLen += 2 // auth len requestLen += 2 // auth len
requestLen += len(hello.Auth) requestLen += len(hello.Auth)
_request := buf.StackNewSize(requestLen) request := buf.NewSize(requestLen)
defer common.KeepAlive(_request)
request := common.Dup(_request)
defer request.Release() defer request.Release()
common.Must( common.Must(
request.WriteByte(Version), request.WriteByte(Version),
@@ -99,9 +97,7 @@ func ReadServerHello(stream io.Reader) (*ServerHello, error) {
responseLen += 8 // sendBPS responseLen += 8 // sendBPS
responseLen += 8 // recvBPS responseLen += 8 // recvBPS
responseLen += 2 // message len responseLen += 2 // message len
_response := buf.StackNewSize(responseLen) response := buf.NewSize(responseLen)
defer common.KeepAlive(_response)
response := common.Dup(_response)
defer response.Release() defer response.Release()
_, err := response.ReadFullFrom(stream, responseLen) _, err := response.ReadFullFrom(stream, responseLen)
if err != nil { if err != nil {
@@ -131,9 +127,7 @@ func WriteServerHello(stream io.Writer, hello ServerHello) error {
responseLen += 8 // recvBPS responseLen += 8 // recvBPS
responseLen += 2 // message len responseLen += 2 // message len
responseLen += len(hello.Message) responseLen += len(hello.Message)
_response := buf.StackNewSize(responseLen) response := buf.NewSize(responseLen)
defer common.KeepAlive(_response)
response := common.Dup(_response)
defer response.Release() defer response.Release()
if hello.OK { if hello.OK {
common.Must(response.WriteByte(1)) common.Must(response.WriteByte(1))
@@ -185,9 +179,7 @@ func WriteClientRequest(stream io.Writer, request ClientRequest) error {
requestLen += 2 // host len requestLen += 2 // host len
requestLen += len(request.Host) requestLen += len(request.Host)
requestLen += 2 // port requestLen += 2 // port
_buffer := buf.StackNewSize(requestLen) buffer := buf.NewSize(requestLen)
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release() defer buffer.Release()
if request.UDP { if request.UDP {
common.Must(buffer.WriteByte(1)) common.Must(buffer.WriteByte(1))
@@ -213,9 +205,7 @@ func ReadServerResponse(stream io.Reader) (*ServerResponse, error) {
responseLen += 1 // ok responseLen += 1 // ok
responseLen += 4 // udp session id responseLen += 4 // udp session id
responseLen += 2 // message len responseLen += 2 // message len
_response := buf.StackNewSize(responseLen) response := buf.NewSize(responseLen)
defer common.KeepAlive(_response)
response := common.Dup(_response)
defer response.Release() defer response.Release()
_, err := response.ReadFullFrom(stream, responseLen) _, err := response.ReadFullFrom(stream, responseLen)
if err != nil { if err != nil {
@@ -243,9 +233,7 @@ func WriteServerResponse(stream io.Writer, response ServerResponse) error {
responseLen += 4 // udp session id responseLen += 4 // udp session id
responseLen += 2 // message len responseLen += 2 // message len
responseLen += len(response.Message) responseLen += len(response.Message)
_buffer := buf.StackNewSize(responseLen) buffer := buf.NewSize(responseLen)
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release() defer buffer.Release()
if response.OK { if response.OK {
common.Must(buffer.WriteByte(1)) common.Must(buffer.WriteByte(1))
@@ -338,12 +326,10 @@ func WriteUDPMessage(conn quic.Connection, message UDPMessage) error {
messageLen += 1 // frag count messageLen += 1 // frag count
messageLen += 2 // data len messageLen += 2 // data len
messageLen += len(message.Data) messageLen += len(message.Data)
_buffer := buf.StackNewSize(messageLen) buffer := buf.NewSize(messageLen)
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release() defer buffer.Release()
err := writeUDPMessage(conn, message, buffer) err := writeUDPMessage(conn, message, buffer)
if errSize, ok := err.(quic.ErrMessageToLarge); ok { if errSize, ok := err.(quic.ErrMessageTooLarge); ok {
// need to frag // need to frag
message.MsgID = uint16(rand.Intn(0xFFFF)) + 1 // msgID must be > 0 when fragCount > 1 message.MsgID = uint16(rand.Intn(0xFFFF)) + 1 // msgID must be > 0 when fragCount > 1
fragMsgs := FragUDPMessage(message, int(errSize)) fragMsgs := FragUDPMessage(message, int(errSize))

View File

@@ -4,7 +4,6 @@ import (
"crypto/sha256" "crypto/sha256"
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"io"
"net" "net"
"os" "os"
@@ -72,17 +71,6 @@ func (c *ClientConn) WriteBuffer(buffer *buf.Buffer) error {
return nil return nil
} }
func (c *ClientConn) ReadFrom(r io.Reader) (n int64, err error) {
if !c.headerWritten {
return bufio.ReadFrom0(c, r)
}
return bufio.Copy(c.ExtendedConn, r)
}
func (c *ClientConn) WriteTo(w io.Writer) (n int64, err error) {
return bufio.Copy(w, c.ExtendedConn)
}
func (c *ClientConn) FrontHeadroom() int { func (c *ClientConn) FrontHeadroom() int {
if !c.headerWritten { if !c.headerWritten {
return KeyLength + 5 + M.MaxSocksaddrLength return KeyLength + 5 + M.MaxSocksaddrLength
@@ -203,39 +191,18 @@ func ClientHandshakeRaw(conn net.Conn, key [KeyLength]byte, command byte, destin
func ClientHandshake(conn net.Conn, key [KeyLength]byte, destination M.Socksaddr, payload []byte) error { func ClientHandshake(conn net.Conn, key [KeyLength]byte, destination M.Socksaddr, payload []byte) error {
headerLen := KeyLength + M.SocksaddrSerializer.AddrPortLen(destination) + 5 headerLen := KeyLength + M.SocksaddrSerializer.AddrPortLen(destination) + 5
var header *buf.Buffer header := buf.NewSize(headerLen + len(payload))
defer header.Release() defer header.Release()
var writeHeader bool
if len(payload) > 0 && headerLen+len(payload) < 65535 {
buffer := buf.StackNewSize(headerLen + len(payload))
defer common.KeepAlive(buffer)
header = common.Dup(buffer)
} else {
buffer := buf.StackNewSize(headerLen)
defer common.KeepAlive(buffer)
header = common.Dup(buffer)
writeHeader = true
}
common.Must1(header.Write(key[:])) common.Must1(header.Write(key[:]))
common.Must1(header.Write(CRLF)) common.Must1(header.Write(CRLF))
common.Must(header.WriteByte(CommandTCP)) common.Must(header.WriteByte(CommandTCP))
common.Must(M.SocksaddrSerializer.WriteAddrPort(header, destination)) common.Must(M.SocksaddrSerializer.WriteAddrPort(header, destination))
common.Must1(header.Write(CRLF)) common.Must1(header.Write(CRLF))
if !writeHeader { common.Must1(header.Write(payload))
common.Must1(header.Write(payload))
}
_, err := conn.Write(header.Bytes()) _, err := conn.Write(header.Bytes())
if err != nil { if err != nil {
return E.Cause(err, "write request") return E.Cause(err, "write request")
} }
if writeHeader {
_, err = conn.Write(payload)
if err != nil {
return E.Cause(err, "write payload")
}
}
return nil return nil
} }
@@ -258,14 +225,12 @@ func ClientHandshakePacket(conn net.Conn, key [KeyLength]byte, destination M.Soc
headerLen := KeyLength + 2*M.SocksaddrSerializer.AddrPortLen(destination) + 9 headerLen := KeyLength + 2*M.SocksaddrSerializer.AddrPortLen(destination) + 9
payloadLen := payload.Len() payloadLen := payload.Len()
var header *buf.Buffer var header *buf.Buffer
defer header.Release()
var writeHeader bool var writeHeader bool
if payload.Start() >= headerLen { if payload.Start() >= headerLen {
header = buf.With(payload.ExtendHeader(headerLen)) header = buf.With(payload.ExtendHeader(headerLen))
} else { } else {
buffer := buf.StackNewSize(headerLen) header = buf.NewSize(headerLen)
defer common.KeepAlive(buffer) defer header.Release()
header = common.Dup(buffer)
writeHeader = true writeHeader = true
} }
common.Must1(header.Write(key[:])) common.Must1(header.Write(key[:]))
@@ -309,7 +274,7 @@ func ReadPacket(conn net.Conn, buffer *buf.Buffer) (M.Socksaddr, error) {
} }
_, err = buffer.ReadFullFrom(conn, int(length)) _, err = buffer.ReadFullFrom(conn, int(length))
return destination, err return destination.Unwrap(), err
} }
func WritePacket(conn net.Conn, buffer *buf.Buffer, destination M.Socksaddr) error { func WritePacket(conn net.Conn, buffer *buf.Buffer, destination M.Socksaddr) error {

View File

@@ -4,7 +4,6 @@ import (
"context" "context"
"net" "net"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/auth" "github.com/sagernet/sing/common/auth"
"github.com/sagernet/sing/common/buf" "github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio" "github.com/sagernet/sing/common/bufio"
@@ -59,7 +58,7 @@ func (s *Service[K]) UpdateUsers(userList []K, passwordList []string) error {
func (s *Service[K]) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error { func (s *Service[K]) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
var key [KeyLength]byte var key [KeyLength]byte
n, err := conn.Read(common.Dup(key[:])) n, err := conn.Read(key[:])
if err != nil { if err != nil {
return err return err
} else if n != KeyLength { } else if n != KeyLength {

View File

@@ -75,7 +75,7 @@ func (c *Client) offerNew() (quic.Connection, error) {
} }
var packetConn net.PacketConn var packetConn net.PacketConn
packetConn = bufio.NewUnbindPacketConn(udpConn) packetConn = bufio.NewUnbindPacketConn(udpConn)
quicConn, err := quic.Dial(packetConn, udpConn.RemoteAddr(), c.serverAddr.AddrString(), c.tlsConfig, c.quicConfig) quicConn, err := quic.Dial(c.ctx, packetConn, udpConn.RemoteAddr(), c.tlsConfig, c.quicConfig)
if err != nil { if err != nil {
packetConn.Close() packetConn.Close()
return nil, err return nil, err

Some files were not shown because too many files have changed in this diff Show More