Skip to content

Commit 5a91eb9

Browse files
committed
Remove unused ICMP replies & Improve tcpbuf options
1 parent 11d9f26 commit 5a91eb9

7 files changed

+122
-289
lines changed

stack_gvisor.go

+61-25
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ package tun
55
import (
66
"context"
77
"net/netip"
8-
"os"
8+
"runtime"
99
"time"
1010

1111
"github.com/sagernet/gvisor/pkg/tcpip"
@@ -17,6 +17,7 @@ import (
1717
"github.com/sagernet/gvisor/pkg/tcpip/transport/icmp"
1818
"github.com/sagernet/gvisor/pkg/tcpip/transport/tcp"
1919
"github.com/sagernet/gvisor/pkg/tcpip/transport/udp"
20+
"github.com/sagernet/gvisor/pkg/waiter"
2021
E "github.com/sagernet/sing/common/exceptions"
2122
"github.com/sagernet/sing/common/logger"
2223
M "github.com/sagernet/sing/common/metadata"
@@ -77,17 +78,35 @@ func (t *GVisor) Start() error {
7778
destination := M.SocksaddrFrom(AddrFromAddress(r.ID().LocalAddress), r.ID().LocalPort)
7879
pErr := t.handler.PrepareConnection(N.NetworkTCP, source, destination)
7980
if pErr != nil {
80-
r.Complete(gWriteUnreachable(t.stack, r.Packet(), err) == os.ErrInvalid)
81+
r.Complete(pErr != ErrDrop)
8182
return
8283
}
83-
conn := &gLazyConn{
84-
parentCtx: t.ctx,
85-
stack: t.stack,
86-
request: r,
87-
localAddr: source.TCPAddr(),
88-
remoteAddr: destination.TCPAddr(),
84+
var (
85+
wq waiter.Queue
86+
endpoint tcpip.Endpoint
87+
tErr tcpip.Error
88+
)
89+
handshakeCtx, cancel := context.WithCancel(context.Background())
90+
go func() {
91+
select {
92+
case <-t.ctx.Done():
93+
wq.Notify(wq.Events())
94+
case <-handshakeCtx.Done():
95+
}
96+
}()
97+
endpoint, tErr = r.CreateEndpoint(&wq)
98+
cancel()
99+
if tErr != nil {
100+
r.Complete(true)
101+
return
89102
}
90-
go t.handler.NewConnectionEx(t.ctx, conn, source, destination, nil)
103+
r.Complete(false)
104+
endpoint.SocketOptions().SetKeepAlive(true)
105+
keepAliveIdle := tcpip.KeepaliveIdleOption(15 * time.Second)
106+
endpoint.SetSockOpt(&keepAliveIdle)
107+
keepAliveInterval := tcpip.KeepaliveIntervalOption(15 * time.Second)
108+
endpoint.SetSockOpt(&keepAliveInterval)
109+
go t.handler.NewConnectionEx(t.ctx, gonet.NewTCPConn(&wq, endpoint), source, destination, nil)
91110
})
92111
ipStack.SetTransportProtocolHandler(tcp.ProtocolNumber, tcpForwarder.HandlePacket)
93112
ipStack.SetTransportProtocolHandler(udp.ProtocolNumber, NewUDPForwarder(t.ctx, ipStack, t.handler, t.udpTimeout).HandlePacket)
@@ -134,30 +153,47 @@ func newGVisorStack(ep stack.LinkEndpoint) (*stack.Stack, error) {
134153
icmp.NewProtocol6,
135154
},
136155
})
137-
tErr := ipStack.CreateNIC(defaultNIC, ep)
138-
if tErr != nil {
139-
return nil, E.New("create nic: ", gonet.TranslateNetstackError(tErr))
156+
err := ipStack.CreateNIC(defaultNIC, ep)
157+
if err != nil {
158+
return nil, gonet.TranslateNetstackError(err)
140159
}
141160
ipStack.SetRouteTable([]tcpip.Route{
142161
{Destination: header.IPv4EmptySubnet, NIC: defaultNIC},
143162
{Destination: header.IPv6EmptySubnet, NIC: defaultNIC},
144163
})
145-
ipStack.SetSpoofing(defaultNIC, true)
146-
ipStack.SetPromiscuousMode(defaultNIC, true)
147-
bufSize := 20 * 1024
148-
ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &tcpip.TCPReceiveBufferSizeRangeOption{
149-
Min: 1,
150-
Default: bufSize,
151-
Max: bufSize,
152-
})
153-
ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &tcpip.TCPSendBufferSizeRangeOption{
154-
Min: 1,
155-
Default: bufSize,
156-
Max: bufSize,
157-
})
164+
err = ipStack.SetSpoofing(defaultNIC, true)
165+
if err != nil {
166+
return nil, gonet.TranslateNetstackError(err)
167+
}
168+
err = ipStack.SetPromiscuousMode(defaultNIC, true)
169+
if err != nil {
170+
return nil, gonet.TranslateNetstackError(err)
171+
}
158172
sOpt := tcpip.TCPSACKEnabled(true)
159173
ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &sOpt)
160174
mOpt := tcpip.TCPModerateReceiveBufferOption(true)
161175
ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &mOpt)
176+
if runtime.GOOS == "windows" {
177+
tcpRecoveryOpt := tcpip.TCPRecovery(0)
178+
err = ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &tcpRecoveryOpt)
179+
}
180+
tcpRXBufOpt := tcpip.TCPReceiveBufferSizeRangeOption{
181+
Min: tcpRXBufMinSize,
182+
Default: tcpRXBufDefSize,
183+
Max: tcpRXBufMaxSize,
184+
}
185+
err = ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &tcpRXBufOpt)
186+
if err != nil {
187+
return nil, gonet.TranslateNetstackError(err)
188+
}
189+
tcpTXBufOpt := tcpip.TCPSendBufferSizeRangeOption{
190+
Min: tcpTXBufMinSize,
191+
Default: tcpTXBufDefSize,
192+
Max: tcpTXBufMaxSize,
193+
}
194+
err = ipStack.SetTransportProtocolOption(tcp.ProtocolNumber, &tcpTXBufOpt)
195+
if err != nil {
196+
return nil, gonet.TranslateNetstackError(err)
197+
}
162198
return ipStack, nil
163199
}

stack_gvisor_lazy.go

-228
This file was deleted.

stack_gvisor_tcpbuf_default.go

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) Tailscale Inc & AUTHORS
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
4+
//go:build with_gvisor && !ios
5+
6+
package tun
7+
8+
import "github.com/sagernet/gvisor/pkg/tcpip/transport/tcp"
9+
10+
const (
11+
tcpRXBufMinSize = tcp.MinBufferSize
12+
tcpRXBufDefSize = tcp.DefaultSendBufferSize
13+
tcpRXBufMaxSize = 8 << 20 // 8MiB
14+
15+
tcpTXBufMinSize = tcp.MinBufferSize
16+
tcpTXBufDefSize = tcp.DefaultReceiveBufferSize
17+
tcpTXBufMaxSize = 6 << 20 // 6MiB
18+
)

stack_gvisor_tcpbuf_ios.go

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright (c) Tailscale Inc & AUTHORS
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
4+
//go:build with_gvisor
5+
6+
package tun
7+
8+
import "github.com/sagernet/gvisor/pkg/tcpip/transport/tcp"
9+
10+
const (
11+
// tcp{RX,TX}Buf{Min,Def,Max}Size mirror gVisor defaults. We leave these
12+
// unchanged on iOS for now as to not increase pressure towards the
13+
// NetworkExtension memory limit.
14+
tcpRXBufMinSize = tcp.MinBufferSize
15+
tcpRXBufDefSize = tcp.DefaultSendBufferSize
16+
tcpRXBufMaxSize = tcp.MaxBufferSize
17+
18+
tcpTXBufMinSize = tcp.MinBufferSize
19+
tcpTXBufDefSize = tcp.DefaultReceiveBufferSize
20+
tcpTXBufMaxSize = tcp.MaxBufferSize
21+
)

0 commit comments

Comments
 (0)