diff --git a/listener/tun/ipstack/gvisor/tcp.go b/listener/tun/ipstack/gvisor/tcp.go index 660912cb..b5dad6ea 100644 --- a/listener/tun/ipstack/gvisor/tcp.go +++ b/listener/tun/ipstack/gvisor/tcp.go @@ -1,10 +1,10 @@ -//go:build !no_gvisor - package gvisor import ( + "net" "time" + "github.com/Dreamacro/clash/common/pool" "github.com/Dreamacro/clash/listener/tun/ipstack/gvisor/adapter" "github.com/Dreamacro/clash/listener/tun/ipstack/gvisor/option" "github.com/Dreamacro/clash/log" @@ -20,17 +20,17 @@ import ( const ( // defaultWndSize if set to zero, the default // receive window buffer size is used instead. - defaultWndSize = 0 + defaultWndSize = pool.RelayBufferSize // maxConnAttempts specifies the maximum number // of in-flight tcp connection attempts. - maxConnAttempts = 2 << 10 + maxConnAttempts = 1 << 10 // tcpKeepaliveCount is the maximum number of // TCP keep-alive probes to send before giving up // and killing the connection if no response is // obtained from the other end. - tcpKeepaliveCount = 9 + tcpKeepaliveCount = 8 // tcpKeepaliveIdle specifies the time a connection // must remain idle before the first TCP keepalive @@ -66,18 +66,26 @@ func withTCPHandler(handle adapter.TCPHandleFunc) option.Option { r.Complete(true) return } - defer r.Complete(false) err = setSocketOptions(s, ep) if err != nil { + ep.Close() r.Complete(true) return } + defer r.Complete(false) conn := &tcpConn{ TCPConn: gonet.NewTCPConn(&wq, ep), id: id, } + + if conn.RemoteAddr() == nil { + log.Warnln("[STACK] endpoint is not connected, current state: %v", tcp.EndpointState(ep.State())) + _ = conn.Close() + return + } + handle(conn) }) s.SetTransportProtocolHandler(tcp.ProtocolNumber, tcpForwarder.HandlePacket) @@ -125,3 +133,17 @@ type tcpConn struct { func (c *tcpConn) ID() *stack.TransportEndpointID { return &c.id } + +func (c *tcpConn) LocalAddr() net.Addr { + return &net.TCPAddr{ + IP: net.IP(c.id.LocalAddress), + Port: int(c.id.LocalPort), + } +} + +func (c *tcpConn) RemoteAddr() net.Addr { + return &net.TCPAddr{ + IP: net.IP(c.id.RemoteAddress), + Port: int(c.id.RemotePort), + } +} diff --git a/listener/tun/ipstack/gvisor/udp.go b/listener/tun/ipstack/gvisor/udp.go index f010ed8a..7abdd046 100644 --- a/listener/tun/ipstack/gvisor/udp.go +++ b/listener/tun/ipstack/gvisor/udp.go @@ -49,6 +49,20 @@ func (c *udpConn) ID() *stack.TransportEndpointID { return &c.id } +func (c *udpConn) LocalAddr() net.Addr { + return &net.UDPAddr{ + IP: net.IP(c.id.LocalAddress), + Port: int(c.id.LocalPort), + } +} + +func (c *udpConn) RemoteAddr() net.Addr { + return &net.UDPAddr{ + IP: net.IP(c.id.RemoteAddress), + Port: int(c.id.RemotePort), + } +} + type packet struct { pc adapter.UDPConn rAddr net.Addr