github.com/xtls/xray-core@v1.8.12-0.20240518155711-3168d27b0bdb/common/singbridge/reader.go (about)

     1  package singbridge
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/sagernet/sing/common"
     7  	"github.com/sagernet/sing/common/bufio"
     8  	N "github.com/sagernet/sing/common/network"
     9  	"github.com/xtls/xray-core/common/buf"
    10  	"github.com/xtls/xray-core/common/net"
    11  )
    12  
    13  var (
    14  	_ buf.Reader        = (*Conn)(nil)
    15  	_ buf.TimeoutReader = (*Conn)(nil)
    16  	_ buf.Writer        = (*Conn)(nil)
    17  )
    18  
    19  type Conn struct {
    20  	net.Conn
    21  	writer N.VectorisedWriter
    22  }
    23  
    24  func NewConn(conn net.Conn) *Conn {
    25  	writer, _ := bufio.CreateVectorisedWriter(conn)
    26  	return &Conn{
    27  		Conn:   conn,
    28  		writer: writer,
    29  	}
    30  }
    31  
    32  func (c *Conn) ReadMultiBuffer() (buf.MultiBuffer, error) {
    33  	buffer, err := buf.ReadBuffer(c.Conn)
    34  	if err != nil {
    35  		return nil, err
    36  	}
    37  	return buf.MultiBuffer{buffer}, nil
    38  }
    39  
    40  func (c *Conn) ReadMultiBufferTimeout(duration time.Duration) (buf.MultiBuffer, error) {
    41  	err := c.SetReadDeadline(time.Now().Add(duration))
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  	defer c.SetReadDeadline(time.Time{})
    46  	return c.ReadMultiBuffer()
    47  }
    48  
    49  func (c *Conn) WriteMultiBuffer(bufferList buf.MultiBuffer) error {
    50  	defer buf.ReleaseMulti(bufferList)
    51  	if c.writer != nil {
    52  		bytesList := make([][]byte, len(bufferList))
    53  		for i, buffer := range bufferList {
    54  			bytesList[i] = buffer.Bytes()
    55  		}
    56  		return common.Error(bufio.WriteVectorised(c.writer, bytesList))
    57  	}
    58  	// Since this conn is only used by tun, we don't force buffer writes to merge.
    59  	for _, buffer := range bufferList {
    60  		_, err := c.Conn.Write(buffer.Bytes())
    61  		if err != nil {
    62  			return err
    63  		}
    64  	}
    65  	return nil
    66  }