diff --git a/constant/timeout.go b/constant/timeout.go index 627f93ba..d3a2db6e 100644 --- a/constant/timeout.go +++ b/constant/timeout.go @@ -11,4 +11,5 @@ const ( DNSTimeout = 10 * time.Second QUICTimeout = 30 * time.Second STUNTimeout = 15 * time.Second + UDPTimeout = 5 * time.Minute ) diff --git a/go.mod b/go.mod index 01b2da76..4d1092cf 100644 --- a/go.mod +++ b/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 diff --git a/go.sum b/go.sum index baee45e5..31ea0601 100644 --- a/go.sum +++ b/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= diff --git a/inbound/direct.go b/inbound/direct.go index ca514e83..aefcafaf 100644 --- a/inbound/direct.go +++ b/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 diff --git a/inbound/shadowsocks.go b/inbound/shadowsocks.go index b1c221f4..0c26392c 100644 --- a/inbound/shadowsocks.go +++ b/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 { diff --git a/inbound/shadowsocks_multi.go b/inbound/shadowsocks_multi.go index b724a45b..7e7309d5 100644 --- a/inbound/shadowsocks_multi.go +++ b/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, diff --git a/inbound/shadowsocks_relay.go b/inbound/shadowsocks_relay.go index 8cecaa24..22c67cf0 100644 --- a/inbound/shadowsocks_relay.go +++ b/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, diff --git a/inbound/tproxy.go b/inbound/tproxy.go index c28cbca4..55dcac56 100644 --- a/inbound/tproxy.go +++ b/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 diff --git a/inbound/tun.go b/inbound/tun.go index b57a6782..60c07ece 100644 --- a/inbound/tun.go +++ b/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 diff --git a/option/tun.go b/option/tun.go index 7e80cfe2..ff068f3b 100644 --- a/option/tun.go +++ b/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 } diff --git a/test/go.mod b/test/go.mod index b7847a9c..72d24492 100644 --- a/test/go.mod +++ b/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 diff --git a/test/go.sum b/test/go.sum index faa114bb..c0340ffa 100644 --- a/test/go.sum +++ b/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=