Improve read wait interface &

Refactor Authenticator interface to struct
This commit is contained in:
世界
2023-12-07 11:56:57 +08:00
parent 4197805a22
commit c8b4182ea3
22 changed files with 291 additions and 320 deletions

View File

@@ -17,16 +17,16 @@ func (c *NATPacketConn) CreatePacketReadWaiter() (N.PacketReadWaiter, bool) {
type waitNATPacketConn struct {
*NATPacketConn
waiter N.PacketReadWaiter
readWaiter N.PacketReadWaiter
}
func (c *waitNATPacketConn) InitializeReadWaiter(newBuffer func() *buf.Buffer) {
c.waiter.InitializeReadWaiter(newBuffer)
func (c *waitNATPacketConn) InitializeReadWaiter(options N.ReadWaitOptions) (needCopy bool) {
return c.readWaiter.InitializeReadWaiter(options)
}
func (c *waitNATPacketConn) WaitReadPacket() (destination M.Socksaddr, err error) {
destination, err = c.waiter.WaitReadPacket()
if socksaddrWithoutPort(destination) == c.origin {
func (c *waitNATPacketConn) WaitReadPacket() (buffer *buf.Buffer, destination M.Socksaddr, err error) {
buffer, destination, err = c.readWaiter.WaitReadPacket()
if err == nil && socksaddrWithoutPort(destination) == c.origin {
destination = M.Socksaddr{
Addr: c.destination.Addr,
Fqdn: c.destination.Fqdn,

View File

@@ -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)
}

View File

@@ -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 {

View 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
}

View File

@@ -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) {

View 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
}

View File

@@ -76,11 +76,8 @@ func (c *ClientBind) connect() (*wireConn, error) {
return nil, err
}
c.conn = &wireConn{
PacketConn: &bufio.UnbindPacketConn{
ExtendedConn: bufio.NewExtendedConn(udpConn),
Addr: c.connectAddr,
},
done: make(chan struct{}),
PacketConn: bufio.NewUnbindPacketConn(udpConn),
done: make(chan struct{}),
}
} else {
udpConn, err := c.dialer.ListenPacket(c.ctx, M.Socksaddr{Addr: netip.IPv4Unspecified()})