| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 | package internalimport (	"io"	"net"	"sync"	"time"	v2net "v2ray.com/core/common/net")// ConnectionID is the ID of a connection.type ConnectionID struct {	Local      v2net.Address	Remote     v2net.Address	RemotePort v2net.Port}// NewConnectionID creates a new ConnectionId.func NewConnectionID(source v2net.Address, dest v2net.Destination) ConnectionID {	return ConnectionID{		Local:      source,		Remote:     dest.Address,		RemotePort: dest.Port,	}}// Reuser determines whether a connection can be reused or not.type Reuser struct {	// userEnabled indicates connection-reuse enabled by user.	userEnabled bool	// appEnabled indicates connection-reuse enabled by app.	appEnabled bool}// ReuseConnection returns a tracker for tracking connection reusability.func ReuseConnection(reuse bool) *Reuser {	return &Reuser{		userEnabled: reuse,		appEnabled:  reuse,	}}// Connection is an implementation of net.Conn with re-usability.type Connection struct {	sync.RWMutex	id       ConnectionID	conn     net.Conn	listener ConnectionRecyler	reuser   *Reuser}// NewConnection creates a new connection.func NewConnection(id ConnectionID, conn net.Conn, manager ConnectionRecyler, reuser *Reuser) *Connection {	return &Connection{		id:       id,		conn:     conn,		listener: manager,		reuser:   reuser,	}}// Read implements net.Conn.Read().func (v *Connection) Read(b []byte) (int, error) {	conn := v.underlyingConn()	if conn == nil {		return 0, io.EOF	}	return conn.Read(b)}// Write implement net.Conn.Write().func (v *Connection) Write(b []byte) (int, error) {	conn := v.underlyingConn()	if conn == nil {		return 0, io.ErrClosedPipe	}	return conn.Write(b)}// Close implements net.Conn.Close(). If the connection is reusable, the underlying connection will be recycled.func (v *Connection) Close() error {	if v == nil {		return io.ErrClosedPipe	}	v.Lock()	defer v.Unlock()	if v.conn == nil {		return io.ErrClosedPipe	}	if v.Reusable() {		v.listener.Put(v.id, v.conn)		return nil	}	err := v.conn.Close()	v.conn = nil	return err}// LocalAddr implements net.Conn.LocalAddr().func (v *Connection) LocalAddr() net.Addr {	conn := v.underlyingConn()	if conn == nil {		return nil	}	return conn.LocalAddr()}// RemoteAddr implements net.Conn.RemoteAddr().func (v *Connection) RemoteAddr() net.Addr {	conn := v.underlyingConn()	if conn == nil {		return nil	}	return conn.RemoteAddr()}// SetDeadline implements net.Conn.SetDeadline().func (v *Connection) SetDeadline(t time.Time) error {	conn := v.underlyingConn()	if conn == nil {		return nil	}	return conn.SetDeadline(t)}// SetReadDeadline implements net.Conn.SetReadDeadline().func (v *Connection) SetReadDeadline(t time.Time) error {	conn := v.underlyingConn()	if conn == nil {		return nil	}	return conn.SetReadDeadline(t)}// SetWriteDeadline implements net.Conn.SetWriteDeadline().func (v *Connection) SetWriteDeadline(t time.Time) error {	conn := v.underlyingConn()	if conn == nil {		return nil	}	return conn.SetWriteDeadline(t)}// SetReusable implements internet.Reusable.SetReusable().func (v *Connection) SetReusable(reusable bool) {	if v == nil {		return	}	v.reuser.appEnabled = reusable}// Reusable implements internet.Reusable.Reusable().func (v *Connection) Reusable() bool {	if v == nil {		return false	}	return v.reuser.userEnabled && v.reuser.appEnabled}// SysFd implement internet.SysFd.SysFd().func (v *Connection) SysFd() (int, error) {	conn := v.underlyingConn()	if conn == nil {		return 0, io.ErrClosedPipe	}	return GetSysFd(conn)}func (v *Connection) underlyingConn() net.Conn {	if v == nil {		return nil	}	v.RLock()	defer v.RUnlock()	return v.conn}
 |