Add endpoint independent nat support for tun inbound

This commit is contained in:
世界 2022-07-26 19:21:56 +08:00
parent 0347a7c038
commit f008d0bde3
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
12 changed files with 54 additions and 36 deletions

View file

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

2
go.mod
View file

@ -15,7 +15,7 @@ require (
github.com/sagernet/sing v0.0.0-20220726034811-bc109486f14e github.com/sagernet/sing v0.0.0-20220726034811-bc109486f14e
github.com/sagernet/sing-dns v0.0.0-20220726044716-2b8c696b09f5 github.com/sagernet/sing-dns v0.0.0-20220726044716-2b8c696b09f5
github.com/sagernet/sing-shadowsocks v0.0.0-20220726034922-ebbaadcae06b 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/sagernet/sing-vmess v0.0.0-20220726034841-4dae776653e5
github.com/spf13/cobra v1.5.0 github.com/spf13/cobra v1.5.0
github.com/stretchr/testify v1.8.0 github.com/stretchr/testify v1.8.0

4
go.sum
View file

@ -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-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 h1:6wJoJaroW3WCGjHGu7XPOSLEKP9Loi3Ox4+7A1kRTsQ=
github.com/sagernet/sing-shadowsocks v0.0.0-20220726034922-ebbaadcae06b/go.mod h1:mH6wE4b5FZp1Q/meATe4tjiPjvQO9E7Lr0FBBwFYp4I= 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-20220726111504-b4bded886e01 h1:tNJn7T87sgQyA8gpEvC6LbusV4lkhZU8oi4mRujOhM8=
github.com/sagernet/sing-tun v0.0.0-20220725225208-3b0c717db3f5/go.mod h1:p7QbUBs2ejf6UQsiHyy1xGAWOk9JWQjZTHy8pOmkWmo= 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 h1:TNguWTPF6gxX/gR02hY3LGviUn6LGlDPofE6lpSJWeo=
github.com/sagernet/sing-vmess v0.0.0-20220726034841-4dae776653e5/go.mod h1:Q8csko2kQZHRZTz8ztqELrJB22HV60/tztPVgACV84E= 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= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,10 +1,12 @@
package option package option
type TunInboundOptions struct { type TunInboundOptions struct {
InterfaceName string `json:"interface_name,omitempty"` InterfaceName string `json:"interface_name,omitempty"`
MTU uint32 `json:"mtu,omitempty"` MTU uint32 `json:"mtu,omitempty"`
Inet4Address *ListenPrefix `json:"inet4_address,omitempty"` Inet4Address *ListenPrefix `json:"inet4_address,omitempty"`
Inet6Address *ListenPrefix `json:"inet6_address,omitempty"` Inet6Address *ListenPrefix `json:"inet6_address,omitempty"`
AutoRoute bool `json:"auto_route,omitempty"` AutoRoute bool `json:"auto_route,omitempty"`
EndpointIndependentNat bool `json:"endpoint_independent_nat,omitempty"`
UDPTimeout int64 `json:"udp_timeout,omitempty"`
InboundOptions InboundOptions
} }

View file

@ -51,7 +51,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sagernet/sing-dns v0.0.0-20220726044716-2b8c696b09f5 // 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-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/sagernet/sing-vmess v0.0.0-20220726034841-4dae776653e5 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect github.com/sirupsen/logrus v1.8.1 // indirect
github.com/vishvananda/netlink v1.1.0 // indirect github.com/vishvananda/netlink v1.1.0 // indirect

View file

@ -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-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 h1:6wJoJaroW3WCGjHGu7XPOSLEKP9Loi3Ox4+7A1kRTsQ=
github.com/sagernet/sing-shadowsocks v0.0.0-20220726034922-ebbaadcae06b/go.mod h1:mH6wE4b5FZp1Q/meATe4tjiPjvQO9E7Lr0FBBwFYp4I= 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-20220726111504-b4bded886e01 h1:tNJn7T87sgQyA8gpEvC6LbusV4lkhZU8oi4mRujOhM8=
github.com/sagernet/sing-tun v0.0.0-20220725225208-3b0c717db3f5/go.mod h1:p7QbUBs2ejf6UQsiHyy1xGAWOk9JWQjZTHy8pOmkWmo= 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 h1:TNguWTPF6gxX/gR02hY3LGviUn6LGlDPofE6lpSJWeo=
github.com/sagernet/sing-vmess v0.0.0-20220726034841-4dae776653e5/go.mod h1:Q8csko2kQZHRZTz8ztqELrJB22HV60/tztPVgACV84E= 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= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=