github.com/sagernet/sing@v0.2.6/common/bufio/fallback.go (about)

     1  package bufio
     2  
     3  import (
     4  	"net"
     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.NetPacketConn = (*FallbackPacketConn)(nil)
    12  
    13  type FallbackPacketConn struct {
    14  	N.PacketConn
    15  }
    16  
    17  func NewNetPacketConn(conn N.PacketConn) N.NetPacketConn {
    18  	if packetConn, loaded := conn.(N.NetPacketConn); loaded {
    19  		return packetConn
    20  	}
    21  	return &FallbackPacketConn{PacketConn: conn}
    22  }
    23  
    24  func (c *FallbackPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
    25  	buffer := buf.With(p)
    26  	destination, err := c.ReadPacket(buffer)
    27  	if err != nil {
    28  		return
    29  	}
    30  	n = buffer.Len()
    31  	if buffer.Start() > 0 {
    32  		copy(p, buffer.Bytes())
    33  	}
    34  	addr = destination.UDPAddr()
    35  	return
    36  }
    37  
    38  func (c *FallbackPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
    39  	err = c.WritePacket(buf.As(p), M.SocksaddrFromNet(addr))
    40  	if err == nil {
    41  		n = len(p)
    42  	}
    43  	return
    44  }
    45  
    46  func (c *FallbackPacketConn) ReaderReplaceable() bool {
    47  	return true
    48  }
    49  
    50  func (c *FallbackPacketConn) WriterReplaceable() bool {
    51  	return true
    52  }
    53  
    54  func (c *FallbackPacketConn) Upstream() any {
    55  	return c.PacketConn
    56  }