Browse Source

Add endpoint independent nat support for tun inbound

世界 3 years ago
parent
commit
f008d0bde3
12 changed files with 54 additions and 36 deletions
  1. 1 0
      constant/timeout.go
  2. 1 1
      go.mod
  3. 2 2
      go.sum
  4. 1 1
      inbound/direct.go
  5. 1 1
      inbound/shadowsocks.go
  6. 1 1
      inbound/shadowsocks_multi.go
  7. 1 1
      inbound/shadowsocks_relay.go
  8. 1 1
      inbound/tproxy.go
  9. 35 20
      inbound/tun.go
  10. 7 5
      option/tun.go
  11. 1 1
      test/go.mod
  12. 2 2
      test/go.sum

+ 1 - 0
constant/timeout.go

@@ -11,4 +11,5 @@ const (
 	DNSTimeout             = 10 * time.Second
 	QUICTimeout            = 30 * time.Second
 	STUNTimeout            = 15 * time.Second
+	UDPTimeout             = 5 * time.Minute
 )

+ 1 - 1
go.mod

@@ -15,7 +15,7 @@ require (
 	github.com/sagernet/sing v0.0.0-20220726034811-bc109486f14e
 	github.com/sagernet/sing-dns v0.0.0-20220726044716-2b8c696b09f5
 	github.com/sagernet/sing-shadowsocks v0.0.0-20220726034922-ebbaadcae06b
-	github.com/sagernet/sing-tun v0.0.0-20220725225208-3b0c717db3f5
+	github.com/sagernet/sing-tun v0.0.0-20220726111504-b4bded886e01
 	github.com/sagernet/sing-vmess v0.0.0-20220726034841-4dae776653e5
 	github.com/spf13/cobra v1.5.0
 	github.com/stretchr/testify v1.8.0

+ 2 - 2
go.sum

@@ -149,8 +149,8 @@ github.com/sagernet/sing-dns v0.0.0-20220726044716-2b8c696b09f5 h1:l6ztUAFVhWhY0
 github.com/sagernet/sing-dns v0.0.0-20220726044716-2b8c696b09f5/go.mod h1:KL+8wZG3gqHLm+nvNI3ZNaPzCMA4T7KIwsGp7ix9a34=
 github.com/sagernet/sing-shadowsocks v0.0.0-20220726034922-ebbaadcae06b h1:6wJoJaroW3WCGjHGu7XPOSLEKP9Loi3Ox4+7A1kRTsQ=
 github.com/sagernet/sing-shadowsocks v0.0.0-20220726034922-ebbaadcae06b/go.mod h1:mH6wE4b5FZp1Q/meATe4tjiPjvQO9E7Lr0FBBwFYp4I=
-github.com/sagernet/sing-tun v0.0.0-20220725225208-3b0c717db3f5 h1:i8L1e3A3v/UerH577y4wTghN8nooQOLuIP+Z+N4q5jA=
-github.com/sagernet/sing-tun v0.0.0-20220725225208-3b0c717db3f5/go.mod h1:p7QbUBs2ejf6UQsiHyy1xGAWOk9JWQjZTHy8pOmkWmo=
+github.com/sagernet/sing-tun v0.0.0-20220726111504-b4bded886e01 h1:tNJn7T87sgQyA8gpEvC6LbusV4lkhZU8oi4mRujOhM8=
+github.com/sagernet/sing-tun v0.0.0-20220726111504-b4bded886e01/go.mod h1:bYHamPB16GFGt34ayYt56Pb7aN64RPY0+uuFPBSbj0U=
 github.com/sagernet/sing-vmess v0.0.0-20220726034841-4dae776653e5 h1:TNguWTPF6gxX/gR02hY3LGviUn6LGlDPofE6lpSJWeo=
 github.com/sagernet/sing-vmess v0.0.0-20220726034841-4dae776653e5/go.mod h1:Q8csko2kQZHRZTz8ztqELrJB22HV60/tztPVgACV84E=
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=

+ 1 - 1
inbound/direct.go

@@ -50,7 +50,7 @@ func NewDirect(ctx context.Context, router adapter.Router, logger log.ContextLog
 	if options.UDPTimeout != 0 {
 		udpTimeout = options.UDPTimeout
 	} else {
-		udpTimeout = 300
+		udpTimeout = int64(C.UDPTimeout.Seconds())
 	}
 	inbound.udpNat = udpnat.New[netip.AddrPort](udpTimeout, adapter.NewUpstreamContextHandler(inbound.newConnection, inbound.newPacketConnection, inbound))
 	inbound.connHandler = inbound

+ 1 - 1
inbound/shadowsocks.go

@@ -55,7 +55,7 @@ func newShadowsocks(ctx context.Context, router adapter.Router, logger log.Conte
 	if options.UDPTimeout != 0 {
 		udpTimeout = options.UDPTimeout
 	} else {
-		udpTimeout = 300
+		udpTimeout = int64(C.UDPTimeout.Seconds())
 	}
 	var err error
 	switch {

+ 1 - 1
inbound/shadowsocks_multi.go

@@ -44,7 +44,7 @@ func newShadowsocksMulti(ctx context.Context, router adapter.Router, logger log.
 	if options.UDPTimeout != 0 {
 		udpTimeout = options.UDPTimeout
 	} else {
-		udpTimeout = 300
+		udpTimeout = int64(C.UDPTimeout.Seconds())
 	}
 	service, err := shadowaead_2022.NewMultiServiceWithPassword[int](
 		options.Method,

+ 1 - 1
inbound/shadowsocks_relay.go

@@ -44,7 +44,7 @@ func newShadowsocksRelay(ctx context.Context, router adapter.Router, logger log.
 	if options.UDPTimeout != 0 {
 		udpTimeout = options.UDPTimeout
 	} else {
-		udpTimeout = 300
+		udpTimeout = int64(C.UDPTimeout.Seconds())
 	}
 	service, err := shadowaead_2022.NewRelayServiceWithPassword[int](
 		options.Method,

+ 1 - 1
inbound/tproxy.go

@@ -39,7 +39,7 @@ func NewTProxy(ctx context.Context, router adapter.Router, logger log.ContextLog
 	if options.UDPTimeout != 0 {
 		udpTimeout = options.UDPTimeout
 	} else {
-		udpTimeout = 300
+		udpTimeout = int64(C.UDPTimeout.Seconds())
 	}
 	tproxy.connHandler = tproxy
 	tproxy.oobPacketHandler = tproxy

+ 35 - 20
inbound/tun.go

@@ -8,8 +8,10 @@ import (
 	"net/netip"
 	"strconv"
 	"strings"
+	"time"
 
 	"github.com/sagernet/sing-box/adapter"
+	"github.com/sagernet/sing-box/common/canceler"
 	C "github.com/sagernet/sing-box/constant"
 	"github.com/sagernet/sing-box/log"
 	"github.com/sagernet/sing-box/option"
@@ -27,15 +29,17 @@ var _ adapter.Inbound = (*Tun)(nil)
 type Tun struct {
 	tag string
 
-	ctx            context.Context
-	router         adapter.Router
-	logger         log.ContextLogger
-	inboundOptions option.InboundOptions
-	tunName        string
-	tunMTU         uint32
-	inet4Address   netip.Prefix
-	inet6Address   netip.Prefix
-	autoRoute      bool
+	ctx                    context.Context
+	router                 adapter.Router
+	logger                 log.ContextLogger
+	inboundOptions         option.InboundOptions
+	tunName                string
+	tunMTU                 uint32
+	inet4Address           netip.Prefix
+	inet6Address           netip.Prefix
+	autoRoute              bool
+	endpointIndependentNat bool
+	udpTimeout             int64
 
 	tunIf    tun.Tun
 	tunStack *tun.GVisorTun
@@ -50,17 +54,25 @@ func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger
 	if tunMTU == 0 {
 		tunMTU = 1500
 	}
+	var udpTimeout int64
+	if options.UDPTimeout != 0 {
+		udpTimeout = options.UDPTimeout
+	} else {
+		udpTimeout = int64(C.UDPTimeout.Seconds())
+	}
 	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,
+		tunName:                tunName,
+		tunMTU:                 tunMTU,
+		inet4Address:           options.Inet4Address.Build(),
+		inet6Address:           options.Inet6Address.Build(),
+		autoRoute:              options.AutoRoute,
+		endpointIndependentNat: options.EndpointIndependentNat,
+		udpTimeout:             udpTimeout,
 	}, nil
 }
 
@@ -78,7 +90,7 @@ func (t *Tun) Start() error {
 		return E.Cause(err, "configure tun interface")
 	}
 	t.tunIf = tunIf
-	t.tunStack = tun.NewGVisor(t.ctx, tunIf, t.tunMTU, t)
+	t.tunStack = tun.NewGVisor(t.ctx, tunIf, t.tunMTU, t.endpointIndependentNat, t.udpTimeout, t)
 	err = t.tunStack.Start()
 	if err != nil {
 		return err
@@ -116,6 +128,9 @@ func (t *Tun) NewConnection(ctx context.Context, conn net.Conn, upstreamMetadata
 
 func (t *Tun) NewPacketConnection(ctx context.Context, conn N.PacketConn, upstreamMetadata M.Metadata) error {
 	ctx = log.ContextWithNewID(ctx)
+	if tun.NeedTimeoutFromContext(ctx) {
+		ctx, conn = canceler.NewPacketConn(ctx, conn, time.Duration(t.udpTimeout)*time.Second)
+	}
 	var metadata adapter.InboundContext
 	metadata.Inbound = t.tag
 	metadata.InboundType = C.TypeTun

+ 7 - 5
option/tun.go

@@ -1,10 +1,12 @@
 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"`
+	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"`
 	InboundOptions
 }

+ 1 - 1
test/go.mod

@@ -51,7 +51,7 @@ require (
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/sagernet/sing-dns v0.0.0-20220726044716-2b8c696b09f5 // indirect
 	github.com/sagernet/sing-shadowsocks v0.0.0-20220726034922-ebbaadcae06b // indirect
-	github.com/sagernet/sing-tun v0.0.0-20220725225208-3b0c717db3f5 // indirect
+	github.com/sagernet/sing-tun v0.0.0-20220726111504-b4bded886e01 // indirect
 	github.com/sagernet/sing-vmess v0.0.0-20220726034841-4dae776653e5 // indirect
 	github.com/sirupsen/logrus v1.8.1 // indirect
 	github.com/vishvananda/netlink v1.1.0 // indirect

+ 2 - 2
test/go.sum

@@ -174,8 +174,8 @@ github.com/sagernet/sing-dns v0.0.0-20220726044716-2b8c696b09f5 h1:l6ztUAFVhWhY0
 github.com/sagernet/sing-dns v0.0.0-20220726044716-2b8c696b09f5/go.mod h1:KL+8wZG3gqHLm+nvNI3ZNaPzCMA4T7KIwsGp7ix9a34=
 github.com/sagernet/sing-shadowsocks v0.0.0-20220726034922-ebbaadcae06b h1:6wJoJaroW3WCGjHGu7XPOSLEKP9Loi3Ox4+7A1kRTsQ=
 github.com/sagernet/sing-shadowsocks v0.0.0-20220726034922-ebbaadcae06b/go.mod h1:mH6wE4b5FZp1Q/meATe4tjiPjvQO9E7Lr0FBBwFYp4I=
-github.com/sagernet/sing-tun v0.0.0-20220725225208-3b0c717db3f5 h1:i8L1e3A3v/UerH577y4wTghN8nooQOLuIP+Z+N4q5jA=
-github.com/sagernet/sing-tun v0.0.0-20220725225208-3b0c717db3f5/go.mod h1:p7QbUBs2ejf6UQsiHyy1xGAWOk9JWQjZTHy8pOmkWmo=
+github.com/sagernet/sing-tun v0.0.0-20220726111504-b4bded886e01 h1:tNJn7T87sgQyA8gpEvC6LbusV4lkhZU8oi4mRujOhM8=
+github.com/sagernet/sing-tun v0.0.0-20220726111504-b4bded886e01/go.mod h1:bYHamPB16GFGt34ayYt56Pb7aN64RPY0+uuFPBSbj0U=
 github.com/sagernet/sing-vmess v0.0.0-20220726034841-4dae776653e5 h1:TNguWTPF6gxX/gR02hY3LGviUn6LGlDPofE6lpSJWeo=
 github.com/sagernet/sing-vmess v0.0.0-20220726034841-4dae776653e5/go.mod h1:Q8csko2kQZHRZTz8ztqELrJB22HV60/tztPVgACV84E=
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=