github.com/xraypb/xray-core@v1.6.6/proxy/shadowsocks_2022/shadowsocks_2022.go (about)

     1  package shadowsocks_2022
     2  
     3  import (
     4  	"io"
     5  
     6  	B "github.com/sagernet/sing/common/buf"
     7  	E "github.com/sagernet/sing/common/exceptions"
     8  	M "github.com/sagernet/sing/common/metadata"
     9  	"github.com/xraypb/xray-core/common/buf"
    10  	"github.com/xraypb/xray-core/common/net"
    11  )
    12  
    13  //go:generate go run github.com/xraypb/xray-core/common/errors/errorgen
    14  
    15  func toDestination(socksaddr M.Socksaddr, network net.Network) net.Destination {
    16  	if socksaddr.IsFqdn() {
    17  		return net.Destination{
    18  			Network: network,
    19  			Address: net.DomainAddress(socksaddr.Fqdn),
    20  			Port:    net.Port(socksaddr.Port),
    21  		}
    22  	} else {
    23  		return net.Destination{
    24  			Network: network,
    25  			Address: net.IPAddress(socksaddr.Addr.AsSlice()),
    26  			Port:    net.Port(socksaddr.Port),
    27  		}
    28  	}
    29  }
    30  
    31  func toSocksaddr(destination net.Destination) M.Socksaddr {
    32  	var addr M.Socksaddr
    33  	switch destination.Address.Family() {
    34  	case net.AddressFamilyDomain:
    35  		addr.Fqdn = destination.Address.Domain()
    36  	default:
    37  		addr.Addr = M.AddrFromIP(destination.Address.IP())
    38  	}
    39  	addr.Port = uint16(destination.Port)
    40  	return addr
    41  }
    42  
    43  type pipeConnWrapper struct {
    44  	R io.Reader
    45  	W buf.Writer
    46  	net.Conn
    47  }
    48  
    49  func (w *pipeConnWrapper) Close() error {
    50  	return nil
    51  }
    52  
    53  func (w *pipeConnWrapper) Read(b []byte) (n int, err error) {
    54  	return w.R.Read(b)
    55  }
    56  
    57  func (w *pipeConnWrapper) Write(p []byte) (n int, err error) {
    58  	n = len(p)
    59  	var mb buf.MultiBuffer
    60  	pLen := len(p)
    61  	for pLen > 0 {
    62  		buffer := buf.New()
    63  		if pLen > buf.Size {
    64  			_, err = buffer.Write(p[:buf.Size])
    65  			p = p[buf.Size:]
    66  		} else {
    67  			buffer.Write(p)
    68  		}
    69  		pLen -= int(buffer.Len())
    70  		mb = append(mb, buffer)
    71  	}
    72  	err = w.W.WriteMultiBuffer(mb)
    73  	if err != nil {
    74  		n = 0
    75  		buf.ReleaseMulti(mb)
    76  	}
    77  	return
    78  }
    79  
    80  type packetConnWrapper struct {
    81  	buf.Reader
    82  	buf.Writer
    83  	net.Conn
    84  	Dest   net.Destination
    85  	cached buf.MultiBuffer
    86  }
    87  
    88  func (w *packetConnWrapper) ReadPacket(buffer *B.Buffer) (M.Socksaddr, error) {
    89  	if w.cached != nil {
    90  		mb, bb := buf.SplitFirst(w.cached)
    91  		if bb == nil {
    92  			w.cached = nil
    93  		} else {
    94  			buffer.Write(bb.Bytes())
    95  			w.cached = mb
    96  			var destination net.Destination
    97  			if bb.UDP != nil {
    98  				destination = *bb.UDP
    99  			} else {
   100  				destination = w.Dest
   101  			}
   102  			bb.Release()
   103  			return toSocksaddr(destination), nil
   104  		}
   105  	}
   106  	mb, err := w.ReadMultiBuffer()
   107  	if err != nil {
   108  		return M.Socksaddr{}, err
   109  	}
   110  	nb, bb := buf.SplitFirst(mb)
   111  	if bb == nil {
   112  		return M.Socksaddr{}, nil
   113  	} else {
   114  		buffer.Write(bb.Bytes())
   115  		w.cached = nb
   116  		var destination net.Destination
   117  		if bb.UDP != nil {
   118  			destination = *bb.UDP
   119  		} else {
   120  			destination = w.Dest
   121  		}
   122  		bb.Release()
   123  		return toSocksaddr(destination), nil
   124  	}
   125  }
   126  
   127  func (w *packetConnWrapper) WritePacket(buffer *B.Buffer, destination M.Socksaddr) error {
   128  	vBuf := buf.New()
   129  	vBuf.Write(buffer.Bytes())
   130  	endpoint := toDestination(destination, net.Network_UDP)
   131  	vBuf.UDP = &endpoint
   132  	return w.Writer.WriteMultiBuffer(buf.MultiBuffer{vBuf})
   133  }
   134  
   135  func (w *packetConnWrapper) Close() error {
   136  	buf.ReleaseMulti(w.cached)
   137  	return nil
   138  }
   139  
   140  func returnError(err error) error {
   141  	if E.IsClosed(err) {
   142  		return nil
   143  	}
   144  	return err
   145  }