Преглед изворни кода

Add uid and android user rules support in tun routing

世界 пре 3 година
родитељ
комит
3157593b6b
10 измењених фајлова са 176 додато и 90 уклоњено
  1. 6 9
      .golangci.yml
  2. 7 13
      Makefile
  3. 8 0
      docs/changelog.md
  4. 58 1
      docs/configuration/inbound/tun.md
  5. 3 3
      go.mod
  6. 6 6
      go.sum
  7. 69 44
      inbound/tun.go
  8. 13 8
      option/tun.go
  9. 2 2
      test/go.mod
  10. 4 4
      test/go.sum

+ 6 - 9
.golangci.yml

@@ -3,18 +3,15 @@ linters:
   enable:
     - gofumpt
     - govet
-    - gci
+#    - gci
     - staticcheck
     - paralleltest
 
-issues:
-  fix: true
-
 linters-settings:
-  gci:
-    sections:
-      - standard
-      - prefix(github.com/sagernet/)
-      - default
+#  gci:
+#    sections:
+#      - standard
+#      - prefix(github.com/sagernet/)
+#      - default
   staticcheck:
     go: '1.19'

+ 7 - 13
Makefile

@@ -1,7 +1,7 @@
 NAME = sing-box
 COMMIT = $(shell git rev-parse --short HEAD)
 TAGS ?= with_quic,with_clash_api
-PARAMS = -trimpath -tags '$(TAGS)' -ldflags \
+PARAMS = -v -trimpath -tags '$(TAGS)' -ldflags \
 		'-X "github.com/sagernet/sing-box/constant.Commit=$(COMMIT)" \
 		-w -s -buildid='
 MAIN = ./cmd/sing-box
@@ -11,26 +11,17 @@ MAIN = ./cmd/sing-box
 build:
 	go build $(PARAMS) $(MAIN)
 
-action_version: build
-	echo "::set-output name=VERSION::`./sing-box version -n`"
-
 install:
 	go install $(PARAMS) $(MAIN)
 
-release:
-	goreleaser release --snapshot --rm-dist
-
-fmt_install:
-	go install -v mvdan.cc/gofumpt@latest
-	go install -v github.com/daixiang0/[email protected]
-
 fmt:
 	@gofumpt -l -w .
 	@gofmt -s -w .
 	@gci write -s "standard,prefix(github.com/sagernet/),default" .
 
-lint_install:
-	go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
+fmt_install:
+	go install -v mvdan.cc/gofumpt@latest
+	go install -v github.com/daixiang0/[email protected]
 
 lint:
 	GOOS=linux golangci-lint run ./...
@@ -38,6 +29,9 @@ lint:
 	GOOS=darwin golangci-lint run ./...
 	GOOS=freebsd golangci-lint run ./...
 
+lint_install:
+	go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
+
 test:
 	@go test -v . && \
 	@pushd test && \

+ 8 - 0
docs/changelog.md

@@ -1,3 +1,11 @@
+#### 2022/08/15
+
+* Add uid and android user rules support in [Tun](/configuration/inbound/tun) routing.
+
+#### 2022/08/13
+
+* Fix dns concurrent write
+
 #### 2022/08/12
 
 * Performance improvements

+ 58 - 1
docs/configuration/inbound/tun.md

@@ -19,6 +19,26 @@
       "endpoint_independent_nat": false,
       "udp_timeout": 300,
       "stack": "gvisor",
+      "include_uid": [
+        0
+      ],
+      "include_uid_range": [
+        [
+          1000,
+          99999
+        ]
+      ],
+      "include_android_user": [
+        0,
+        10
+      ],
+      "exclude_uid": [
+        1000
+      ],
+      "exclude_uid_range": [
+        1000,
+        99999
+      ],
       
       "sniff": true,
       "sniff_override_destination": false,
@@ -28,9 +48,13 @@
 }
 ```
 
+!!! note ""
+
+    You can ignore the JSON Array [] tag when the content is only one item
+
 !!! warning ""
 
-    If tun is running in non-privileged mode, the address and MTU will not be configured automatically, please make sure the settings are accurate.
+    If tun is running in non-privileged mode, addresses and MTU will not be configured automatically, please make sure the settings are accurate.
 
 ### Tun Fields
 
@@ -83,6 +107,39 @@ TCP/IP stack.
 
     The LWIP stack is not included by default, see [Installation](/#Installation).
 
+#### include_uid
+
+!!! error ""
+
+    UID and android user rules are only supported on Linux and require auto_route.
+
+Limit users in route. Not limited by default.
+
+#### include_uid_range
+
+Limit users in route, but in range.
+
+#### include_android_user
+
+!!! warning ""
+
+    Only supported on Android
+
+Limit android users in route.
+
+| Common user  | ID  |
+|--------------|-----|
+| Main         | 0   |
+| Work Profile | 10  |
+
+#### exclude_uid
+
+Exclude users in route.
+
+#### exclude_uid_range
+
+Exclude users in route, but in range.
+
 ### Listen Fields
 
 #### sniff

+ 3 - 3
go.mod

@@ -15,17 +15,17 @@ require (
 	github.com/logrusorgru/aurora v2.0.3+incompatible
 	github.com/lucas-clemente/quic-go v0.28.1
 	github.com/oschwald/maxminddb-golang v1.10.0
-	github.com/sagernet/sing v0.0.0-20220813024838-eb2fad956aa8
+	github.com/sagernet/sing v0.0.0-20220814164830-4f2b872a8cbf
 	github.com/sagernet/sing-dns v0.0.0-20220813025814-e656c9dbf3ae
 	github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48
-	github.com/sagernet/sing-tun v0.0.0-20220808133432-d378b6ca536d
+	github.com/sagernet/sing-tun v0.0.0-20220815014658-b828f0164333
 	github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4
 	github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939
 	github.com/spf13/cobra v1.5.0
 	github.com/stretchr/testify v1.8.0
 	go.uber.org/atomic v1.10.0
 	golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
-	golang.org/x/net v0.0.0-20220811182439-13a9a731de15
+	golang.org/x/net v0.0.0-20220812174116-3211cb980234
 	golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab
 )
 

+ 6 - 6
go.sum

@@ -153,14 +153,14 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
 github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805 h1:hE+vtsjBCCPmxkRz9jZA+CicHgVkDT6H+Av5ZzskVxs=
 github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
 github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
-github.com/sagernet/sing v0.0.0-20220813024838-eb2fad956aa8 h1:zTuJbqzZgBh+iGPV41d8ZarKxXPgTq/+PGk1kMhPV8I=
-github.com/sagernet/sing v0.0.0-20220813024838-eb2fad956aa8/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
+github.com/sagernet/sing v0.0.0-20220814164830-4f2b872a8cbf h1:JYnx6N1H2KeFKM7YSH5+qfhvvcy6gpqSpewkp1RLRSg=
+github.com/sagernet/sing v0.0.0-20220814164830-4f2b872a8cbf/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
 github.com/sagernet/sing-dns v0.0.0-20220813025814-e656c9dbf3ae h1:xOpbvgizvIbKKrrcl/CK3RjGY2u7rC+SBXlgqzEZOU4=
 github.com/sagernet/sing-dns v0.0.0-20220813025814-e656c9dbf3ae/go.mod h1:T77zZdE2Cm6VqnFumrpwsq+kxYsbq+vWDhmjtdSl/oM=
 github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48 h1:NlcTFKldteZvYBDyr+V9MjZEI0rAWCSFCyLgPvc5n/Y=
 github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
-github.com/sagernet/sing-tun v0.0.0-20220808133432-d378b6ca536d h1:AQpkoUiF8FxYVI1lf2W9Rbkk914eHjVH9M8y+F/0+Nw=
-github.com/sagernet/sing-tun v0.0.0-20220808133432-d378b6ca536d/go.mod h1:gWwYd53AqXl+Y+q6WlXUc6PkqU28sfu5VTQhyeEIFbw=
+github.com/sagernet/sing-tun v0.0.0-20220815014658-b828f0164333 h1:fJj7jCPkGkbhY/UNwebi7kKq8Yxc6qeD3Jzh9Wk9tPw=
+github.com/sagernet/sing-tun v0.0.0-20220815014658-b828f0164333/go.mod h1:+JztVFWrBR8bbf1fWPCyc4KJ/a1bPejmmoEBj9rI6HQ=
 github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4 h1:2hLETh97+S4WnfMR27XyC7QVU1SH7FTNoCznP229YJU=
 github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4/go.mod h1:82O6gzbxLha/W/jxSVQbsqf2lVdRTjMIgyLug0lpJps=
 github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 h1:pB1Dh1NbwVrLhQhotr4O4Hs3yhiBzmg3AvnUyYjL4x4=
@@ -248,8 +248,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
 golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.0.0-20220811182439-13a9a731de15 h1:cik0bxZUSJVDyaHf1hZPSDsU8SZHGQZQMeueXCE7yBQ=
-golang.org/x/net v0.0.0-20220811182439-13a9a731de15/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
+golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E=
+golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=

+ 69 - 44
inbound/tun.go

@@ -3,7 +3,6 @@ package inbound
 import (
 	"context"
 	"net"
-	"net/netip"
 	"strconv"
 	"strings"
 	"time"
@@ -17,9 +16,9 @@ import (
 	"github.com/sagernet/sing-tun"
 	"github.com/sagernet/sing/common"
 	E "github.com/sagernet/sing/common/exceptions"
-	F "github.com/sagernet/sing/common/format"
 	M "github.com/sagernet/sing/common/metadata"
 	N "github.com/sagernet/sing/common/network"
+	"github.com/sagernet/sing/common/ranges"
 )
 
 var _ adapter.Inbound = (*Tun)(nil)
@@ -30,11 +29,7 @@ type Tun struct {
 	router                 adapter.Router
 	logger                 log.ContextLogger
 	inboundOptions         option.InboundOptions
-	tunName                string
-	tunMTU                 uint32
-	inet4Address           netip.Prefix
-	inet6Address           netip.Prefix
-	autoRoute              bool
+	tunOptions             tun.Options
 	endpointIndependentNat bool
 	udpTimeout             int64
 	stack                  string
@@ -45,7 +40,7 @@ type Tun struct {
 func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TunInboundOptions) (*Tun, error) {
 	tunName := options.InterfaceName
 	if tunName == "" {
-		tunName = mkInterfaceName()
+		tunName = tun.DefaultInterfaceName()
 	}
 	tunMTU := options.MTU
 	if tunMTU == 0 {
@@ -57,23 +52,76 @@ func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger
 	} else {
 		udpTimeout = int64(C.UDPTimeout.Seconds())
 	}
+	includeUID := uidToRange(options.IncludeUID)
+	if len(options.IncludeUIDRange) > 0 {
+		var err error
+		includeUID, err = parseRange(includeUID, options.IncludeUIDRange)
+		if err != nil {
+			return nil, E.Cause(err, "parse include_uid_range")
+		}
+	}
+	excludeUID := uidToRange(options.ExcludeUID)
+	if len(options.ExcludeUIDRange) > 0 {
+		var err error
+		excludeUID, err = parseRange(excludeUID, options.ExcludeUIDRange)
+		if err != nil {
+			return nil, E.Cause(err, "parse exclude_uid_range")
+		}
+	}
 	return &Tun{
-		tag:                    tag,
-		ctx:                    ctx,
-		router:                 router,
-		logger:                 logger,
-		inboundOptions:         options.InboundOptions,
-		tunName:                tunName,
-		tunMTU:                 tunMTU,
-		inet4Address:           options.Inet4Address.Build(),
-		inet6Address:           options.Inet6Address.Build(),
-		autoRoute:              options.AutoRoute,
+		tag:            tag,
+		ctx:            ctx,
+		router:         router,
+		logger:         logger,
+		inboundOptions: options.InboundOptions,
+		tunOptions: tun.Options{
+			Name:               tunName,
+			MTU:                tunMTU,
+			Inet4Address:       options.Inet4Address.Build(),
+			Inet6Address:       options.Inet6Address.Build(),
+			AutoRoute:          options.AutoRoute,
+			IncludeUID:         includeUID,
+			IncludeAndroidUser: options.IncludeAndroidUser,
+			ExcludeUID:         excludeUID,
+		},
 		endpointIndependentNat: options.EndpointIndependentNat,
 		udpTimeout:             udpTimeout,
 		stack:                  options.Stack,
 	}, nil
 }
 
+func uidToRange(uidList option.Listable[uint32]) []ranges.Range[uint32] {
+	return common.Map(uidList, func(uid uint32) ranges.Range[uint32] {
+		return ranges.NewSingle(uid)
+	})
+}
+
+func parseRange(uidRanges []ranges.Range[uint32], rangeList []string) ([]ranges.Range[uint32], error) {
+	for _, uidRange := range rangeList {
+		if !strings.Contains(uidRange, ":") {
+			return nil, E.New("missing ':' in range: ", uidRange)
+		}
+		subIndex := strings.Index(uidRange, ":")
+		if subIndex == 0 {
+			return nil, E.New("missing range start: ", uidRange)
+		} else if subIndex == len(uidRange)-1 {
+			return nil, E.New("missing range end: ", uidRange)
+		}
+		var start, end uint64
+		var err error
+		start, err = strconv.ParseUint(uidRange[:subIndex], 10, 32)
+		if err != nil {
+			return nil, E.Cause(err, "parse range start")
+		}
+		end, err = strconv.ParseUint(uidRange[subIndex+1:], 10, 32)
+		if err != nil {
+			return nil, E.Cause(err, "parse range end")
+		}
+		uidRanges = append(uidRanges, ranges.New(uint32(start), uint32(end)))
+	}
+	return uidRanges, nil
+}
+
 func (t *Tun) Type() string {
 	return C.TypeTun
 }
@@ -83,12 +131,12 @@ func (t *Tun) Tag() string {
 }
 
 func (t *Tun) Start() error {
-	tunIf, err := tun.Open(t.tunName, t.inet4Address, t.inet6Address, t.tunMTU, t.autoRoute)
+	tunIf, err := tun.Open(t.tunOptions)
 	if err != nil {
 		return E.Cause(err, "configure tun interface")
 	}
 	t.tunIf = tunIf
-	t.tunStack, err = tun.NewStack(t.ctx, t.stack, tunIf, t.tunMTU, t.endpointIndependentNat, t.udpTimeout, t)
+	t.tunStack, err = tun.NewStack(t.ctx, t.stack, tunIf, t.tunOptions.MTU, t.endpointIndependentNat, t.udpTimeout, t)
 	if err != nil {
 		return err
 	}
@@ -96,7 +144,7 @@ func (t *Tun) Start() error {
 	if err != nil {
 		return err
 	}
-	t.logger.Info("started at ", t.tunName)
+	t.logger.Info("started at ", t.tunOptions.Name)
 	return nil
 }
 
@@ -153,26 +201,3 @@ func (t *Tun) NewPacketConnection(ctx context.Context, conn N.PacketConn, upstre
 func (t *Tun) NewError(ctx context.Context, err error) {
 	NewError(t.logger, ctx, err)
 }
-
-func mkInterfaceName() (tunName string) {
-	if C.IsDarwin {
-		tunName = "utun"
-	} else {
-		tunName = "tun"
-	}
-	interfaces, err := net.Interfaces()
-	if err != nil {
-		return
-	}
-	var tunIndex int
-	for _, netInterface := range interfaces {
-		if strings.HasPrefix(netInterface.Name, tunName) {
-			index, parseErr := strconv.ParseInt(netInterface.Name[len(tunName):], 10, 16)
-			if parseErr == nil {
-				tunIndex = int(index) + 1
-			}
-		}
-	}
-	tunName = F.ToString(tunName, tunIndex)
-	return
-}

+ 13 - 8
option/tun.go

@@ -1,13 +1,18 @@
 package option
 
 type TunInboundOptions struct {
-	InterfaceName          string        `json:"interface_name,omitempty"`
-	MTU                    uint32        `json:"mtu,omitempty"`
-	Inet4Address           *ListenPrefix `json:"inet4_address,omitempty"`
-	Inet6Address           *ListenPrefix `json:"inet6_address,omitempty"`
-	AutoRoute              bool          `json:"auto_route,omitempty"`
-	EndpointIndependentNat bool          `json:"endpoint_independent_nat,omitempty"`
-	UDPTimeout             int64         `json:"udp_timeout,omitempty"`
-	Stack                  string        `json:"stack,omitempty"`
+	InterfaceName          string           `json:"interface_name,omitempty"`
+	MTU                    uint32           `json:"mtu,omitempty"`
+	Inet4Address           *ListenPrefix    `json:"inet4_address,omitempty"`
+	Inet6Address           *ListenPrefix    `json:"inet6_address,omitempty"`
+	AutoRoute              bool             `json:"auto_route,omitempty"`
+	IncludeUID             Listable[uint32] `json:"include_uid,omitempty"`
+	IncludeUIDRange        Listable[string] `json:"include_uid_range,omitempty"`
+	ExcludeUID             Listable[uint32] `json:"exclude_uid,omitempty"`
+	ExcludeUIDRange        Listable[string] `json:"exclude_uid_range,omitempty"`
+	IncludeAndroidUser     Listable[int]    `json:"android_user,omitempty"`
+	EndpointIndependentNat bool             `json:"endpoint_independent_nat,omitempty"`
+	UDPTimeout             int64            `json:"udp_timeout,omitempty"`
+	Stack                  string           `json:"stack,omitempty"`
 	InboundOptions
 }

+ 2 - 2
test/go.mod

@@ -10,7 +10,7 @@ require (
 	github.com/docker/docker v20.10.17+incompatible
 	github.com/docker/go-connections v0.4.0
 	github.com/gofrs/uuid v4.2.0+incompatible
-	github.com/sagernet/sing v0.0.0-20220813024838-eb2fad956aa8
+	github.com/sagernet/sing v0.0.0-20220814164830-4f2b872a8cbf
 	github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48
 	github.com/spyzhov/ajson v0.7.1
 	github.com/stretchr/testify v1.8.0
@@ -54,7 +54,7 @@ require (
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805 // indirect
 	github.com/sagernet/sing-dns v0.0.0-20220813025814-e656c9dbf3ae // indirect
-	github.com/sagernet/sing-tun v0.0.0-20220808133432-d378b6ca536d // indirect
+	github.com/sagernet/sing-tun v0.0.0-20220815014658-b828f0164333 // indirect
 	github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4 // indirect
 	github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 // indirect
 	github.com/sirupsen/logrus v1.8.1 // indirect

+ 4 - 4
test/go.sum

@@ -175,14 +175,14 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
 github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805 h1:hE+vtsjBCCPmxkRz9jZA+CicHgVkDT6H+Av5ZzskVxs=
 github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
 github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
-github.com/sagernet/sing v0.0.0-20220813024838-eb2fad956aa8 h1:zTuJbqzZgBh+iGPV41d8ZarKxXPgTq/+PGk1kMhPV8I=
-github.com/sagernet/sing v0.0.0-20220813024838-eb2fad956aa8/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
+github.com/sagernet/sing v0.0.0-20220814164830-4f2b872a8cbf h1:JYnx6N1H2KeFKM7YSH5+qfhvvcy6gpqSpewkp1RLRSg=
+github.com/sagernet/sing v0.0.0-20220814164830-4f2b872a8cbf/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
 github.com/sagernet/sing-dns v0.0.0-20220813025814-e656c9dbf3ae h1:xOpbvgizvIbKKrrcl/CK3RjGY2u7rC+SBXlgqzEZOU4=
 github.com/sagernet/sing-dns v0.0.0-20220813025814-e656c9dbf3ae/go.mod h1:T77zZdE2Cm6VqnFumrpwsq+kxYsbq+vWDhmjtdSl/oM=
 github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48 h1:NlcTFKldteZvYBDyr+V9MjZEI0rAWCSFCyLgPvc5n/Y=
 github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
-github.com/sagernet/sing-tun v0.0.0-20220808133432-d378b6ca536d h1:AQpkoUiF8FxYVI1lf2W9Rbkk914eHjVH9M8y+F/0+Nw=
-github.com/sagernet/sing-tun v0.0.0-20220808133432-d378b6ca536d/go.mod h1:gWwYd53AqXl+Y+q6WlXUc6PkqU28sfu5VTQhyeEIFbw=
+github.com/sagernet/sing-tun v0.0.0-20220815014658-b828f0164333 h1:fJj7jCPkGkbhY/UNwebi7kKq8Yxc6qeD3Jzh9Wk9tPw=
+github.com/sagernet/sing-tun v0.0.0-20220815014658-b828f0164333/go.mod h1:+JztVFWrBR8bbf1fWPCyc4KJ/a1bPejmmoEBj9rI6HQ=
 github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4 h1:2hLETh97+S4WnfMR27XyC7QVU1SH7FTNoCznP229YJU=
 github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4/go.mod h1:82O6gzbxLha/W/jxSVQbsqf2lVdRTjMIgyLug0lpJps=
 github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 h1:pB1Dh1NbwVrLhQhotr4O4Hs3yhiBzmg3AvnUyYjL4x4=