@@ -5,7 +5,7 @@ package tun
5
5
import (
6
6
"context"
7
7
"net/netip"
8
- "os "
8
+ "runtime "
9
9
"time"
10
10
11
11
"github.com/sagernet/gvisor/pkg/tcpip"
@@ -17,6 +17,7 @@ import (
17
17
"github.com/sagernet/gvisor/pkg/tcpip/transport/icmp"
18
18
"github.com/sagernet/gvisor/pkg/tcpip/transport/tcp"
19
19
"github.com/sagernet/gvisor/pkg/tcpip/transport/udp"
20
+ "github.com/sagernet/gvisor/pkg/waiter"
20
21
E "github.com/sagernet/sing/common/exceptions"
21
22
"github.com/sagernet/sing/common/logger"
22
23
M "github.com/sagernet/sing/common/metadata"
@@ -77,17 +78,35 @@ func (t *GVisor) Start() error {
77
78
destination := M .SocksaddrFrom (AddrFromAddress (r .ID ().LocalAddress ), r .ID ().LocalPort )
78
79
pErr := t .handler .PrepareConnection (N .NetworkTCP , source , destination )
79
80
if pErr != nil {
80
- r .Complete (gWriteUnreachable ( t . stack , r . Packet (), err ) == os . ErrInvalid )
81
+ r .Complete (pErr != ErrDrop )
81
82
return
82
83
}
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
89
102
}
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 )
91
110
})
92
111
ipStack .SetTransportProtocolHandler (tcp .ProtocolNumber , tcpForwarder .HandlePacket )
93
112
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) {
134
153
icmp .NewProtocol6 ,
135
154
},
136
155
})
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 )
140
159
}
141
160
ipStack .SetRouteTable ([]tcpip.Route {
142
161
{Destination : header .IPv4EmptySubnet , NIC : defaultNIC },
143
162
{Destination : header .IPv6EmptySubnet , NIC : defaultNIC },
144
163
})
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
+ }
158
172
sOpt := tcpip .TCPSACKEnabled (true )
159
173
ipStack .SetTransportProtocolOption (tcp .ProtocolNumber , & sOpt )
160
174
mOpt := tcpip .TCPModerateReceiveBufferOption (true )
161
175
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
+ }
162
198
return ipStack , nil
163
199
}
0 commit comments