Improve read wait interface &
Refactor Authenticator interface to struct & Update smux & Update gVisor to 20231204.0 & Update quic-go to v0.40.1 & Update wireguard-go & Add GSO support for TUN/WireGuard & Fix router pre-start & Fix bind forwarder to interface for systems stack
This commit is contained in:
@@ -53,7 +53,7 @@ func newMuxConnection0(ctx context.Context, stream net.Conn, metadata M.Metadata
|
||||
case CommandTCP:
|
||||
return handler.NewConnection(ctx, stream, metadata)
|
||||
case CommandUDP:
|
||||
return handler.NewPacketConnection(ctx, &PacketConn{stream}, metadata)
|
||||
return handler.NewPacketConnection(ctx, &PacketConn{Conn: stream}, metadata)
|
||||
default:
|
||||
return E.New("unknown command ", command)
|
||||
}
|
||||
|
||||
@@ -85,9 +85,10 @@ func (c *ClientConn) Upstream() any {
|
||||
|
||||
type ClientPacketConn struct {
|
||||
net.Conn
|
||||
access sync.Mutex
|
||||
key [KeyLength]byte
|
||||
headerWritten bool
|
||||
access sync.Mutex
|
||||
key [KeyLength]byte
|
||||
headerWritten bool
|
||||
readWaitOptions N.ReadWaitOptions
|
||||
}
|
||||
|
||||
func NewClientPacketConn(conn net.Conn, key [KeyLength]byte) *ClientPacketConn {
|
||||
|
||||
45
transport/trojan/protocol_wait.go
Normal file
45
transport/trojan/protocol_wait.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package trojan
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/sing/common/rw"
|
||||
)
|
||||
|
||||
var _ N.PacketReadWaiter = (*ClientPacketConn)(nil)
|
||||
|
||||
func (c *ClientPacketConn) InitializeReadWaiter(options N.ReadWaitOptions) (needCopy bool) {
|
||||
c.readWaitOptions = options
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *ClientPacketConn) WaitReadPacket() (buffer *buf.Buffer, destination M.Socksaddr, err error) {
|
||||
destination, err = M.SocksaddrSerializer.ReadAddrPort(c.Conn)
|
||||
if err != nil {
|
||||
return nil, M.Socksaddr{}, E.Cause(err, "read destination")
|
||||
}
|
||||
|
||||
var length uint16
|
||||
err = binary.Read(c.Conn, binary.BigEndian, &length)
|
||||
if err != nil {
|
||||
return nil, M.Socksaddr{}, E.Cause(err, "read chunk length")
|
||||
}
|
||||
|
||||
err = rw.SkipN(c.Conn, 2)
|
||||
if err != nil {
|
||||
return nil, M.Socksaddr{}, E.Cause(err, "skip crlf")
|
||||
}
|
||||
|
||||
buffer = c.readWaitOptions.NewPacketBuffer()
|
||||
_, err = buffer.ReadFullFrom(c.Conn, int(length))
|
||||
if err != nil {
|
||||
buffer.Release()
|
||||
return
|
||||
}
|
||||
c.readWaitOptions.PostReturn(buffer)
|
||||
return
|
||||
}
|
||||
@@ -105,7 +105,7 @@ func (s *Service[K]) NewConnection(ctx context.Context, conn net.Conn, metadata
|
||||
case CommandTCP:
|
||||
return s.handler.NewConnection(ctx, conn, metadata)
|
||||
case CommandUDP:
|
||||
return s.handler.NewPacketConnection(ctx, &PacketConn{conn}, metadata)
|
||||
return s.handler.NewPacketConnection(ctx, &PacketConn{Conn: conn}, metadata)
|
||||
// case CommandMux:
|
||||
default:
|
||||
return HandleMuxConnection(ctx, conn, metadata, s.handler)
|
||||
@@ -122,6 +122,7 @@ func (s *Service[K]) fallback(ctx context.Context, conn net.Conn, metadata M.Met
|
||||
|
||||
type PacketConn struct {
|
||||
net.Conn
|
||||
readWaitOptions N.ReadWaitOptions
|
||||
}
|
||||
|
||||
func (c *PacketConn) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) {
|
||||
|
||||
45
transport/trojan/service_wait.go
Normal file
45
transport/trojan/service_wait.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package trojan
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/sing/common/rw"
|
||||
)
|
||||
|
||||
var _ N.PacketReadWaiter = (*PacketConn)(nil)
|
||||
|
||||
func (c *PacketConn) InitializeReadWaiter(options N.ReadWaitOptions) (needCopy bool) {
|
||||
c.readWaitOptions = options
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *PacketConn) WaitReadPacket() (buffer *buf.Buffer, destination M.Socksaddr, err error) {
|
||||
destination, err = M.SocksaddrSerializer.ReadAddrPort(c.Conn)
|
||||
if err != nil {
|
||||
return nil, M.Socksaddr{}, E.Cause(err, "read destination")
|
||||
}
|
||||
|
||||
var length uint16
|
||||
err = binary.Read(c.Conn, binary.BigEndian, &length)
|
||||
if err != nil {
|
||||
return nil, M.Socksaddr{}, E.Cause(err, "read chunk length")
|
||||
}
|
||||
|
||||
err = rw.SkipN(c.Conn, 2)
|
||||
if err != nil {
|
||||
return nil, M.Socksaddr{}, E.Cause(err, "skip crlf")
|
||||
}
|
||||
|
||||
buffer = c.readWaitOptions.NewPacketBuffer()
|
||||
_, err = buffer.ReadFullFrom(c.Conn, int(length))
|
||||
if err != nil {
|
||||
buffer.Release()
|
||||
return
|
||||
}
|
||||
c.readWaitOptions.PostReturn(buffer)
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user