github.com/sagernet/sing@v0.4.0-beta.19.0.20240518125136-f67a0988a636/common/udpnat/conn_wait.go (about) 1 package udpnat 2 3 import ( 4 "io" 5 6 "github.com/sagernet/sing/common/buf" 7 M "github.com/sagernet/sing/common/metadata" 8 N "github.com/sagernet/sing/common/network" 9 ) 10 11 var _ N.PacketReadWaiter = (*conn)(nil) 12 13 func (c *conn) InitializeReadWaiter(options N.ReadWaitOptions) (needCopy bool) { 14 c.readWaitOptions = options 15 return false 16 } 17 18 func (c *conn) WaitReadPacket() (buffer *buf.Buffer, destination M.Socksaddr, err error) { 19 select { 20 case p := <-c.data: 21 if c.readWaitOptions.NeedHeadroom() { 22 buffer = c.readWaitOptions.NewPacketBuffer() 23 _, err = buffer.Write(p.data.Bytes()) 24 if err != nil { 25 buffer.Release() 26 return 27 } 28 c.readWaitOptions.PostReturn(buffer) 29 p.data.Release() 30 } else { 31 buffer = p.data 32 } 33 destination = p.destination 34 return 35 case <-c.ctx.Done(): 36 return nil, M.Socksaddr{}, io.ErrClosedPipe 37 } 38 }