@@ -5,7 +5,7 @@ package tun
55import (
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}
0 commit comments