github.com/kelleygo/clashcore@v1.0.2/common/net/packet/packet_sing.go (about)

     1  package packet
     2  
     3  import (
     4  	"net"
     5  
     6  	"github.com/sagernet/sing/common/buf"
     7  	"github.com/sagernet/sing/common/bufio"
     8  	M "github.com/sagernet/sing/common/metadata"
     9  	N "github.com/sagernet/sing/common/network"
    10  )
    11  
    12  type SingPacketConn = N.NetPacketConn
    13  
    14  type EnhanceSingPacketConn interface {
    15  	SingPacketConn
    16  	EnhancePacketConn
    17  }
    18  
    19  type enhanceSingPacketConn struct {
    20  	SingPacketConn
    21  	packetReadWaiter N.PacketReadWaiter
    22  }
    23  
    24  func (c *enhanceSingPacketConn) WaitReadFrom() (data []byte, put func(), addr net.Addr, err error) {
    25  	var buff *buf.Buffer
    26  	var dest M.Socksaddr
    27  	rwOptions := N.ReadWaitOptions{}
    28  	if c.packetReadWaiter != nil {
    29  		c.packetReadWaiter.InitializeReadWaiter(rwOptions)
    30  		buff, dest, err = c.packetReadWaiter.WaitReadPacket()
    31  	} else {
    32  		buff = rwOptions.NewPacketBuffer()
    33  		dest, err = c.SingPacketConn.ReadPacket(buff)
    34  		if buff != nil {
    35  			rwOptions.PostReturn(buff)
    36  		}
    37  	}
    38  	if dest.IsFqdn() {
    39  		addr = dest
    40  	} else {
    41  		addr = dest.UDPAddr()
    42  	}
    43  	if err != nil {
    44  		buff.Release()
    45  		return
    46  	}
    47  	if buff == nil {
    48  		return
    49  	}
    50  	if buff.IsEmpty() {
    51  		buff.Release()
    52  		return
    53  	}
    54  	data = buff.Bytes()
    55  	put = buff.Release
    56  	return
    57  }
    58  
    59  func (c *enhanceSingPacketConn) Upstream() any {
    60  	return c.SingPacketConn
    61  }
    62  
    63  func (c *enhanceSingPacketConn) WriterReplaceable() bool {
    64  	return true
    65  }
    66  
    67  func (c *enhanceSingPacketConn) ReaderReplaceable() bool {
    68  	return true
    69  }
    70  
    71  func newEnhanceSingPacketConn(conn SingPacketConn) *enhanceSingPacketConn {
    72  	epc := &enhanceSingPacketConn{SingPacketConn: conn}
    73  	if readWaiter, isReadWaiter := bufio.CreatePacketReadWaiter(conn); isReadWaiter {
    74  		epc.packetReadWaiter = readWaiter
    75  	}
    76  	return epc
    77  }