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  }