github.com/imannamdari/v2ray-core/v5@v5.0.5/proxy/shadowsocks/protocol.go (about)

     1  package shadowsocks
     2  
     3  import (
     4  	"crypto/hmac"
     5  	"crypto/rand"
     6  	"crypto/sha256"
     7  	"hash/crc32"
     8  	"io"
     9  	mrand "math/rand"
    10  	gonet "net"
    11  
    12  	"github.com/imannamdari/v2ray-core/v5/common"
    13  	"github.com/imannamdari/v2ray-core/v5/common/buf"
    14  	"github.com/imannamdari/v2ray-core/v5/common/drain"
    15  	"github.com/imannamdari/v2ray-core/v5/common/net"
    16  	"github.com/imannamdari/v2ray-core/v5/common/protocol"
    17  )
    18  
    19  const (
    20  	Version = 1
    21  )
    22  
    23  var addrParser = protocol.NewAddressParser(
    24  	protocol.AddressFamilyByte(0x01, net.AddressFamilyIPv4),
    25  	protocol.AddressFamilyByte(0x04, net.AddressFamilyIPv6),
    26  	protocol.AddressFamilyByte(0x03, net.AddressFamilyDomain),
    27  	protocol.WithAddressTypeParser(func(b byte) byte {
    28  		return b & 0x0F
    29  	}),
    30  )
    31  
    32  // ReadTCPSession reads a Shadowsocks TCP session from the given reader, returns its header and remaining parts.
    33  func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.RequestHeader, buf.Reader, error) {
    34  	account := user.Account.(*MemoryAccount)
    35  
    36  	hashkdf := hmac.New(sha256.New, []byte("SSBSKDF"))
    37  	hashkdf.Write(account.Key)
    38  
    39  	behaviorSeed := crc32.ChecksumIEEE(hashkdf.Sum(nil))
    40  
    41  	drainer, err := drain.NewBehaviorSeedLimitedDrainer(int64(behaviorSeed), 16+38, 3266, 64)
    42  	if err != nil {
    43  		return nil, nil, newError("failed to initialize drainer").Base(err)
    44  	}
    45  
    46  	buffer := buf.New()
    47  	defer buffer.Release()
    48  
    49  	ivLen := account.Cipher.IVSize()
    50  	var iv []byte
    51  	if ivLen > 0 {
    52  		if _, err := buffer.ReadFullFrom(reader, ivLen); err != nil {
    53  			drainer.AcknowledgeReceive(int(buffer.Len()))
    54  			return nil, nil, drain.WithError(drainer, reader, newError("failed to read IV").Base(err))
    55  		}
    56  
    57  		iv = append([]byte(nil), buffer.BytesTo(ivLen)...)
    58  	}
    59  
    60  	r, err := account.Cipher.NewDecryptionReader(account.Key, iv, reader)
    61  	if err != nil {
    62  		drainer.AcknowledgeReceive(int(buffer.Len()))
    63  		return nil, nil, drain.WithError(drainer, reader, newError("failed to initialize decoding stream").Base(err).AtError())
    64  	}
    65  	br := &buf.BufferedReader{Reader: r}
    66  
    67  	request := &protocol.RequestHeader{
    68  		Version: Version,
    69  		User:    user,
    70  		Command: protocol.RequestCommandTCP,
    71  	}
    72  
    73  	drainer.AcknowledgeReceive(int(buffer.Len()))
    74  	buffer.Clear()
    75  
    76  	addr, port, err := addrParser.ReadAddressPort(buffer, br)
    77  	if err != nil {
    78  		drainer.AcknowledgeReceive(int(buffer.Len()))
    79  		return nil, nil, drain.WithError(drainer, reader, newError("failed to read address").Base(err))
    80  	}
    81  
    82  	request.Address = addr
    83  	request.Port = port
    84  
    85  	if request.Address == nil {
    86  		drainer.AcknowledgeReceive(int(buffer.Len()))
    87  		return nil, nil, drain.WithError(drainer, reader, newError("invalid remote address."))
    88  	}
    89  
    90  	if ivError := account.CheckIV(iv); ivError != nil {
    91  		drainer.AcknowledgeReceive(int(buffer.Len()))
    92  		return nil, nil, drain.WithError(drainer, reader, newError("failed iv check").Base(ivError))
    93  	}
    94  
    95  	return request, br, nil
    96  }
    97  
    98  // WriteTCPRequest writes Shadowsocks request into the given writer, and returns a writer for body.
    99  func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Writer, error) {
   100  	user := request.User
   101  	account := user.Account.(*MemoryAccount)
   102  
   103  	var iv []byte
   104  	if account.Cipher.IVSize() > 0 {
   105  		iv = make([]byte, account.Cipher.IVSize())
   106  		common.Must2(rand.Read(iv))
   107  		if account.ReducedIVEntropy {
   108  			remapToPrintable(iv[:6])
   109  		}
   110  		if ivError := account.CheckIV(iv); ivError != nil {
   111  			return nil, newError("failed to mark outgoing iv").Base(ivError)
   112  		}
   113  		if err := buf.WriteAllBytes(writer, iv); err != nil {
   114  			return nil, newError("failed to write IV")
   115  		}
   116  	}
   117  
   118  	w, err := account.Cipher.NewEncryptionWriter(account.Key, iv, writer)
   119  	if err != nil {
   120  		return nil, newError("failed to create encoding stream").Base(err).AtError()
   121  	}
   122  
   123  	header := buf.New()
   124  
   125  	if err := addrParser.WriteAddressPort(header, request.Address, request.Port); err != nil {
   126  		return nil, newError("failed to write address").Base(err)
   127  	}
   128  
   129  	if err := w.WriteMultiBuffer(buf.MultiBuffer{header}); err != nil {
   130  		return nil, newError("failed to write header").Base(err)
   131  	}
   132  
   133  	return w, nil
   134  }
   135  
   136  func ReadTCPResponse(user *protocol.MemoryUser, reader io.Reader) (buf.Reader, error) {
   137  	account := user.Account.(*MemoryAccount)
   138  
   139  	hashkdf := hmac.New(sha256.New, []byte("SSBSKDF"))
   140  	hashkdf.Write(account.Key)
   141  
   142  	behaviorSeed := crc32.ChecksumIEEE(hashkdf.Sum(nil))
   143  
   144  	drainer, err := drain.NewBehaviorSeedLimitedDrainer(int64(behaviorSeed), 16+38, 3266, 64)
   145  	if err != nil {
   146  		return nil, newError("failed to initialize drainer").Base(err)
   147  	}
   148  
   149  	var iv []byte
   150  	if account.Cipher.IVSize() > 0 {
   151  		iv = make([]byte, account.Cipher.IVSize())
   152  		if n, err := io.ReadFull(reader, iv); err != nil {
   153  			return nil, newError("failed to read IV").Base(err)
   154  		} else { // nolint: revive
   155  			drainer.AcknowledgeReceive(n)
   156  		}
   157  	}
   158  
   159  	if ivError := account.CheckIV(iv); ivError != nil {
   160  		return nil, drain.WithError(drainer, reader, newError("failed iv check").Base(ivError))
   161  	}
   162  
   163  	return account.Cipher.NewDecryptionReader(account.Key, iv, reader)
   164  }
   165  
   166  func WriteTCPResponse(request *protocol.RequestHeader, writer io.Writer) (buf.Writer, error) {
   167  	user := request.User
   168  	account := user.Account.(*MemoryAccount)
   169  
   170  	var iv []byte
   171  	if account.Cipher.IVSize() > 0 {
   172  		iv = make([]byte, account.Cipher.IVSize())
   173  		common.Must2(rand.Read(iv))
   174  		if ivError := account.CheckIV(iv); ivError != nil {
   175  			return nil, newError("failed to mark outgoing iv").Base(ivError)
   176  		}
   177  		if err := buf.WriteAllBytes(writer, iv); err != nil {
   178  			return nil, newError("failed to write IV.").Base(err)
   179  		}
   180  	}
   181  
   182  	return account.Cipher.NewEncryptionWriter(account.Key, iv, writer)
   183  }
   184  
   185  func EncodeUDPPacket(request *protocol.RequestHeader, payload []byte) (*buf.Buffer, error) {
   186  	user := request.User
   187  	account := user.Account.(*MemoryAccount)
   188  
   189  	buffer := buf.New()
   190  	ivLen := account.Cipher.IVSize()
   191  	if ivLen > 0 {
   192  		common.Must2(buffer.ReadFullFrom(rand.Reader, ivLen))
   193  	}
   194  
   195  	if err := addrParser.WriteAddressPort(buffer, request.Address, request.Port); err != nil {
   196  		return nil, newError("failed to write address").Base(err)
   197  	}
   198  
   199  	buffer.Write(payload)
   200  
   201  	if err := account.Cipher.EncodePacket(account.Key, buffer); err != nil {
   202  		return nil, newError("failed to encrypt UDP payload").Base(err)
   203  	}
   204  
   205  	return buffer, nil
   206  }
   207  
   208  func DecodeUDPPacket(user *protocol.MemoryUser, payload *buf.Buffer) (*protocol.RequestHeader, *buf.Buffer, error) {
   209  	account := user.Account.(*MemoryAccount)
   210  
   211  	var iv []byte
   212  	if !account.Cipher.IsAEAD() && account.Cipher.IVSize() > 0 {
   213  		// Keep track of IV as it gets removed from payload in DecodePacket.
   214  		iv = make([]byte, account.Cipher.IVSize())
   215  		copy(iv, payload.BytesTo(account.Cipher.IVSize()))
   216  	}
   217  
   218  	if err := account.Cipher.DecodePacket(account.Key, payload); err != nil {
   219  		return nil, nil, newError("failed to decrypt UDP payload").Base(err)
   220  	}
   221  
   222  	request := &protocol.RequestHeader{
   223  		Version: Version,
   224  		User:    user,
   225  		Command: protocol.RequestCommandUDP,
   226  	}
   227  
   228  	payload.SetByte(0, payload.Byte(0)&0x0F)
   229  
   230  	addr, port, err := addrParser.ReadAddressPort(nil, payload)
   231  	if err != nil {
   232  		return nil, nil, newError("failed to parse address").Base(err)
   233  	}
   234  
   235  	request.Address = addr
   236  	request.Port = port
   237  
   238  	return request, payload, nil
   239  }
   240  
   241  type UDPReader struct {
   242  	Reader io.Reader
   243  	User   *protocol.MemoryUser
   244  }
   245  
   246  func (v *UDPReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
   247  	buffer := buf.New()
   248  	_, err := buffer.ReadFrom(v.Reader)
   249  	if err != nil {
   250  		buffer.Release()
   251  		return nil, err
   252  	}
   253  	_, payload, err := DecodeUDPPacket(v.User, buffer)
   254  	if err != nil {
   255  		buffer.Release()
   256  		return nil, err
   257  	}
   258  	return buf.MultiBuffer{payload}, nil
   259  }
   260  
   261  func (v *UDPReader) ReadFrom(p []byte) (n int, addr gonet.Addr, err error) {
   262  	buffer := buf.New()
   263  	_, err = buffer.ReadFrom(v.Reader)
   264  	if err != nil {
   265  		buffer.Release()
   266  		return 0, nil, err
   267  	}
   268  	vaddr, payload, err := DecodeUDPPacket(v.User, buffer)
   269  	if err != nil {
   270  		buffer.Release()
   271  		return 0, nil, err
   272  	}
   273  	n = copy(p, payload.Bytes())
   274  	payload.Release()
   275  	return n, &gonet.UDPAddr{IP: vaddr.Address.IP(), Port: int(vaddr.Port)}, nil
   276  }
   277  
   278  type UDPWriter struct {
   279  	Writer  io.Writer
   280  	Request *protocol.RequestHeader
   281  }
   282  
   283  // Write implements io.Writer.
   284  func (w *UDPWriter) Write(payload []byte) (int, error) {
   285  	packet, err := EncodeUDPPacket(w.Request, payload)
   286  	if err != nil {
   287  		return 0, err
   288  	}
   289  	_, err = w.Writer.Write(packet.Bytes())
   290  	packet.Release()
   291  	return len(payload), err
   292  }
   293  
   294  func (w *UDPWriter) WriteTo(payload []byte, addr gonet.Addr) (n int, err error) {
   295  	request := *w.Request
   296  	udpAddr := addr.(*gonet.UDPAddr)
   297  	request.Command = protocol.RequestCommandUDP
   298  	request.Address = net.IPAddress(udpAddr.IP)
   299  	request.Port = net.Port(udpAddr.Port)
   300  	packet, err := EncodeUDPPacket(&request, payload)
   301  	if err != nil {
   302  		return 0, err
   303  	}
   304  	_, err = w.Writer.Write(packet.Bytes())
   305  	packet.Release()
   306  	return len(payload), err
   307  }
   308  
   309  func remapToPrintable(input []byte) {
   310  	const charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~\\\""
   311  	seed := mrand.New(mrand.NewSource(int64(crc32.ChecksumIEEE(input))))
   312  	for i := range input {
   313  		input[i] = charSet[seed.Intn(len(charSet))]
   314  	}
   315  }