github.com/yaling888/clash@v1.53.0/transport/vmess/vmess.go (about)

     1  package vmess
     2  
     3  import (
     4  	"fmt"
     5  	"math/rand/v2"
     6  	"net"
     7  	"runtime"
     8  
     9  	"github.com/yaling888/clash/common/uuid"
    10  )
    11  
    12  // Version of vmess
    13  const Version byte = 1
    14  
    15  // Request Options
    16  const (
    17  	OptionChunkStream  byte = 1
    18  	OptionChunkMasking byte = 4
    19  )
    20  
    21  // Security type vmess
    22  type Security = byte
    23  
    24  // Cipher types
    25  const (
    26  	SecurityAES128GCM        Security = 3
    27  	SecurityCHACHA20POLY1305 Security = 4
    28  	SecurityNone             Security = 5
    29  	SecurityZero             Security = 6
    30  )
    31  
    32  // Command types
    33  const (
    34  	CommandTCP byte = 1
    35  	CommandUDP byte = 2
    36  )
    37  
    38  // Addr types
    39  const (
    40  	AtypIPv4       byte = 1
    41  	AtypDomainName byte = 2
    42  	AtypIPv6       byte = 3
    43  )
    44  
    45  // DstAddr store destination address
    46  type DstAddr struct {
    47  	UDP      bool
    48  	AddrType byte
    49  	Addr     []byte
    50  	Port     uint
    51  }
    52  
    53  // Client is vmess connection generator
    54  type Client struct {
    55  	user     []*ID
    56  	uuid     uuid.UUID
    57  	security Security
    58  	isAead   bool
    59  }
    60  
    61  // Config of vmess
    62  type Config struct {
    63  	UUID     string
    64  	AlterID  uint16
    65  	Security string
    66  	Port     string
    67  	HostName string
    68  	IsAead   bool
    69  }
    70  
    71  // StreamConn return a Conn with net.Conn and DstAddr
    72  func (c *Client) StreamConn(conn net.Conn, dst *DstAddr) (net.Conn, error) {
    73  	r := rand.IntN(len(c.user))
    74  	return newConn(conn, c.user[r], dst, c.security, c.isAead)
    75  }
    76  
    77  // NewClient return Client instance
    78  func NewClient(config Config) (*Client, error) {
    79  	uid, err := uuid.ParseStd(config.UUID)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  
    84  	var security Security
    85  	switch config.Security {
    86  	case "aes-128-gcm":
    87  		security = SecurityAES128GCM
    88  	case "chacha20-poly1305":
    89  		security = SecurityCHACHA20POLY1305
    90  	case "none":
    91  		security = SecurityNone
    92  	case "zero":
    93  		security = SecurityZero
    94  	case "auto":
    95  		security = SecurityCHACHA20POLY1305
    96  		if runtime.GOARCH == "amd64" || runtime.GOARCH == "s390x" || runtime.GOARCH == "arm64" {
    97  			security = SecurityAES128GCM
    98  		}
    99  	default:
   100  		return nil, fmt.Errorf("unknown security type: %s", config.Security)
   101  	}
   102  
   103  	return &Client{
   104  		user:     newAlterIDs(newID(uid), config.AlterID),
   105  		uuid:     uid,
   106  		security: security,
   107  		isAead:   config.IsAead,
   108  	}, nil
   109  }