Clash.Meta/common/net/packet/packet_sing.go

80 lines
1.6 KiB
Go
Raw Normal View History

2023-05-15 22:45:08 +08:00
package packet
import (
"net"
"github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type SingPacketConn = N.NetPacketConn
2023-05-19 23:29:43 +08:00
type EnhanceSingPacketConn interface {
SingPacketConn
2023-05-19 23:29:43 +08:00
EnhancePacketConn
}
2023-05-15 22:45:08 +08:00
type enhanceSingPacketConn struct {
SingPacketConn
packetReadWaiter N.PacketReadWaiter
2023-05-15 22:45:08 +08:00
}
func (c *enhanceSingPacketConn) WaitReadFrom() (data []byte, put func(), addr net.Addr, err error) {
var buff *buf.Buffer
var dest M.Socksaddr
newBuffer := func() *buf.Buffer {
buff = buf.NewPacket() // do not use stack buffer
return buff
}
if c.packetReadWaiter != nil {
c.packetReadWaiter.InitializeReadWaiter(newBuffer)
defer c.packetReadWaiter.InitializeReadWaiter(nil)
dest, err = c.packetReadWaiter.WaitReadPacket()
2023-05-15 22:45:08 +08:00
} else {
dest, err = c.SingPacketConn.ReadPacket(newBuffer())
2023-05-15 22:45:08 +08:00
}
if dest.IsFqdn() {
addr = dest
} else {
addr = dest.UDPAddr()
}
if err != nil {
if buff != nil {
buff.Release()
}
return
}
if buff == nil {
return
}
if buff.IsEmpty() {
buff.Release()
return
}
data = buff.Bytes()
put = buff.Release
return
}
func (c *enhanceSingPacketConn) Upstream() any {
return c.SingPacketConn
2023-05-15 22:45:08 +08:00
}
func (c *enhanceSingPacketConn) WriterReplaceable() bool {
return true
}
func (c *enhanceSingPacketConn) ReaderReplaceable() bool {
return true
}
func newEnhanceSingPacketConn(conn SingPacketConn) *enhanceSingPacketConn {
epc := &enhanceSingPacketConn{SingPacketConn: conn}
2023-05-15 22:45:08 +08:00
if readWaiter, isReadWaiter := bufio.CreatePacketReadWaiter(conn); isReadWaiter {
epc.packetReadWaiter = readWaiter
2023-05-15 22:45:08 +08:00
}
return epc
}