github.com/kelleygo/clashcore@v1.0.2/common/net/packet/packet.go (about) 1 package packet 2 3 import ( 4 "net" 5 6 "github.com/kelleygo/clashcore/common/pool" 7 ) 8 9 type WaitReadFrom interface { 10 WaitReadFrom() (data []byte, put func(), addr net.Addr, err error) 11 } 12 13 type EnhancePacketConn interface { 14 net.PacketConn 15 WaitReadFrom 16 } 17 18 func NewEnhancePacketConn(pc net.PacketConn) EnhancePacketConn { 19 if udpConn, isUDPConn := pc.(*net.UDPConn); isUDPConn { 20 return &enhanceUDPConn{UDPConn: udpConn} 21 } 22 if enhancePC, isEnhancePC := pc.(EnhancePacketConn); isEnhancePC { 23 return enhancePC 24 } 25 if singPC, isSingPC := pc.(SingPacketConn); isSingPC { 26 return newEnhanceSingPacketConn(singPC) 27 } 28 return &enhancePacketConn{PacketConn: pc} 29 } 30 31 type enhancePacketConn struct { 32 net.PacketConn 33 } 34 35 func (c *enhancePacketConn) WaitReadFrom() (data []byte, put func(), addr net.Addr, err error) { 36 return waitReadFrom(c.PacketConn) 37 } 38 39 func (c *enhancePacketConn) Upstream() any { 40 return c.PacketConn 41 } 42 43 func (c *enhancePacketConn) WriterReplaceable() bool { 44 return true 45 } 46 47 func (c *enhancePacketConn) ReaderReplaceable() bool { 48 return true 49 } 50 51 func (c *enhanceUDPConn) Upstream() any { 52 return c.UDPConn 53 } 54 55 func (c *enhanceUDPConn) WriterReplaceable() bool { 56 return true 57 } 58 59 func (c *enhanceUDPConn) ReaderReplaceable() bool { 60 return true 61 } 62 63 func waitReadFrom(pc net.PacketConn) (data []byte, put func(), addr net.Addr, err error) { 64 readBuf := pool.Get(pool.UDPBufferSize) 65 put = func() { 66 _ = pool.Put(readBuf) 67 } 68 var readN int 69 readN, addr, err = pc.ReadFrom(readBuf) 70 if readN > 0 { 71 data = readBuf[:readN] 72 } else { 73 put() 74 put = nil 75 } 76 return 77 }