Compare commits

...

3 Commits

Author SHA1 Message Date
世界
bea26198e7 Fix "Fix gLazyConn race" 2025-06-16 14:01:32 +08:00
世界
3df19f464e Fix gLazyConn race 2025-06-13 18:18:53 +08:00
世界
494b0ef858 redirect: Fix unreachable 2025-06-13 18:18:53 +08:00
2 changed files with 71 additions and 56 deletions

View File

@@ -742,9 +742,7 @@ func (r *autoRedirect) nftablesCreateUnreachable(
Data: []byte{uint8(nfProto)},
},
&expr.Counter{},
&expr.Verdict{
Kind: expr.VerdictDrop,
},
&expr.Reject{},
},
})
}

View File

@@ -6,6 +6,7 @@ import (
"context"
"net"
"os"
"sync"
"time"
"github.com/sagernet/gvisor/pkg/tcpip"
@@ -17,19 +18,25 @@ import (
)
type gLazyConn struct {
tcpConn *gonet.TCPConn
parentCtx context.Context
stack *stack.Stack
request *tcp.ForwarderRequest
localAddr net.Addr
remoteAddr net.Addr
handshakeDone bool
handshakeErr error
tcpConn *gonet.TCPConn
parentCtx context.Context
stack *stack.Stack
request *tcp.ForwarderRequest
localAddr net.Addr
remoteAddr net.Addr
handshakeAccess sync.Mutex
handshakeDone bool
handshakeErr error
}
func (c *gLazyConn) HandshakeContext(ctx context.Context) error {
if c.handshakeDone {
return nil
return c.handshakeErr
}
c.handshakeAccess.Lock()
defer c.handshakeAccess.Unlock()
if c.handshakeDone {
return c.handshakeErr
}
defer func() {
c.handshakeDone = true
@@ -64,6 +71,11 @@ func (c *gLazyConn) HandshakeContext(ctx context.Context) error {
}
func (c *gLazyConn) HandshakeFailure(err error) error {
if c.handshakeDone {
return os.ErrInvalid
}
c.handshakeAccess.Lock()
defer c.handshakeAccess.Unlock()
if c.handshakeDone {
return os.ErrInvalid
}
@@ -78,25 +90,17 @@ func (c *gLazyConn) HandshakeSuccess() error {
}
func (c *gLazyConn) Read(b []byte) (n int, err error) {
if !c.handshakeDone {
err = c.HandshakeContext(context.Background())
if err != nil {
return
}
} else if c.handshakeErr != nil {
return 0, c.handshakeErr
err = c.HandshakeContext(context.Background())
if err != nil {
return
}
return c.tcpConn.Read(b)
}
func (c *gLazyConn) Write(b []byte) (n int, err error) {
if !c.handshakeDone {
err = c.HandshakeContext(context.Background())
if err != nil {
return
}
} else if c.handshakeErr != nil {
return 0, c.handshakeErr
err = c.HandshakeContext(context.Background())
if err != nil {
return
}
return c.tcpConn.Write(b)
}
@@ -110,46 +114,41 @@ func (c *gLazyConn) RemoteAddr() net.Addr {
}
func (c *gLazyConn) SetDeadline(t time.Time) error {
if !c.handshakeDone {
err := c.HandshakeContext(context.Background())
if err != nil {
return err
}
} else if c.handshakeErr != nil {
return c.handshakeErr
err := c.HandshakeContext(context.Background())
if err != nil {
return err
}
return c.tcpConn.SetDeadline(t)
}
func (c *gLazyConn) SetReadDeadline(t time.Time) error {
if !c.handshakeDone {
err := c.HandshakeContext(context.Background())
if err != nil {
return err
}
} else if c.handshakeErr != nil {
return c.handshakeErr
err := c.HandshakeContext(context.Background())
if err != nil {
return err
}
return c.tcpConn.SetReadDeadline(t)
}
func (c *gLazyConn) SetWriteDeadline(t time.Time) error {
if !c.handshakeDone {
err := c.HandshakeContext(context.Background())
if err != nil {
return err
}
} else if c.handshakeErr != nil {
return c.handshakeErr
err := c.HandshakeContext(context.Background())
if err != nil {
return err
}
return c.tcpConn.SetWriteDeadline(t)
}
func (c *gLazyConn) Close() error {
if !c.handshakeDone {
c.request.Complete(true)
c.handshakeErr = net.ErrClosed
return nil
c.handshakeAccess.Lock()
if !c.handshakeDone {
c.request.Complete(true)
c.handshakeErr = net.ErrClosed
c.handshakeDone = true
return nil
} else if c.handshakeErr != nil {
return nil
}
c.handshakeAccess.Unlock()
} else if c.handshakeErr != nil {
return nil
}
@@ -158,9 +157,16 @@ func (c *gLazyConn) Close() error {
func (c *gLazyConn) CloseRead() error {
if !c.handshakeDone {
c.request.Complete(true)
c.handshakeErr = net.ErrClosed
return nil
c.handshakeAccess.Lock()
if !c.handshakeDone {
c.request.Complete(true)
c.handshakeErr = net.ErrClosed
c.handshakeDone = true
return nil
} else if c.handshakeErr != nil {
return nil
}
c.handshakeAccess.Unlock()
} else if c.handshakeErr != nil {
return nil
}
@@ -169,9 +175,16 @@ func (c *gLazyConn) CloseRead() error {
func (c *gLazyConn) CloseWrite() error {
if !c.handshakeDone {
c.request.Complete(true)
c.handshakeErr = net.ErrClosed
return nil
c.handshakeAccess.Lock()
if !c.handshakeDone {
c.request.Complete(true)
c.handshakeErr = net.ErrClosed
c.handshakeDone = true
return nil
} else if c.handshakeErr != nil {
return nil
}
c.handshakeAccess.Unlock()
} else if c.handshakeErr != nil {
return nil
}
@@ -179,10 +192,14 @@ func (c *gLazyConn) CloseWrite() error {
}
func (c *gLazyConn) ReaderReplaceable() bool {
c.handshakeAccess.Lock()
defer c.handshakeAccess.Unlock()
return c.handshakeDone && c.handshakeErr == nil
}
func (c *gLazyConn) WriterReplaceable() bool {
c.handshakeAccess.Lock()
defer c.handshakeAccess.Unlock()
return c.handshakeDone && c.handshakeErr == nil
}