github.com/v2fly/v2ray-core/v4@v4.45.2/proxy/shadowsocks/protocol.go (about)

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