github.com/sagernet/sing@v0.4.0-beta.19.0.20240518125136-f67a0988a636/common/bufio/deadline/serial.go (about)

     1  package deadline
     2  
     3  import (
     4  	"net"
     5  	"sync"
     6  
     7  	"github.com/sagernet/sing/common/buf"
     8  	"github.com/sagernet/sing/common/debug"
     9  	M "github.com/sagernet/sing/common/metadata"
    10  	N "github.com/sagernet/sing/common/network"
    11  )
    12  
    13  type SerialConn struct {
    14  	N.ExtendedConn
    15  	access sync.Mutex
    16  }
    17  
    18  func NewSerialConn(conn N.ExtendedConn) N.ExtendedConn {
    19  	if !debug.Enabled {
    20  		return conn
    21  	}
    22  	return &SerialConn{ExtendedConn: conn}
    23  }
    24  
    25  func (c *SerialConn) Read(p []byte) (n int, err error) {
    26  	if !c.access.TryLock() {
    27  		panic("concurrent read on deadline conn")
    28  	}
    29  	defer c.access.Unlock()
    30  	return c.ExtendedConn.Read(p)
    31  }
    32  
    33  func (c *SerialConn) ReadBuffer(buffer *buf.Buffer) error {
    34  	if !c.access.TryLock() {
    35  		panic("concurrent read on deadline conn")
    36  	}
    37  	defer c.access.Unlock()
    38  	return c.ExtendedConn.ReadBuffer(buffer)
    39  }
    40  
    41  func (c *SerialConn) Upstream() any {
    42  	return c.ExtendedConn
    43  }
    44  
    45  type SerialPacketConn struct {
    46  	N.NetPacketConn
    47  	access sync.Mutex
    48  }
    49  
    50  func NewSerialPacketConn(conn N.NetPacketConn) N.NetPacketConn {
    51  	if !debug.Enabled {
    52  		return conn
    53  	}
    54  	return &SerialPacketConn{NetPacketConn: conn}
    55  }
    56  
    57  func (c *SerialPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
    58  	if !c.access.TryLock() {
    59  		panic("concurrent read on deadline conn")
    60  	}
    61  	defer c.access.Unlock()
    62  	return c.NetPacketConn.ReadFrom(p)
    63  }
    64  
    65  func (c *SerialPacketConn) ReadPacket(buffer *buf.Buffer) (destination M.Socksaddr, err error) {
    66  	if !c.access.TryLock() {
    67  		panic("concurrent read on deadline conn")
    68  	}
    69  	defer c.access.Unlock()
    70  	return c.NetPacketConn.ReadPacket(buffer)
    71  }
    72  
    73  func (c *SerialPacketConn) Upstream() any {
    74  	return c.NetPacketConn
    75  }