github.com/igoogolx/clash@v1.19.8/transport/vmess/vmess.go (about) 1 package vmess 2 3 import ( 4 "fmt" 5 "math/rand" 6 "net" 7 "runtime" 8 9 "github.com/gofrs/uuid/v5" 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 isVless bool 60 } 61 62 // Config of vmess 63 type Config struct { 64 UUID string 65 AlterID uint16 66 Security string 67 Port string 68 HostName string 69 IsAead bool 70 IsVless bool 71 } 72 73 // StreamConn return a Conn with net.Conn and DstAddr 74 func (c *Client) StreamConn(conn net.Conn, dst *DstAddr) (net.Conn, error) { 75 r := rand.Intn(len(c.user)) 76 return newConn(conn, c.user[r], dst, c.security, c.isAead, c.isVless) 77 } 78 79 // NewClient return Client instance 80 func NewClient(config Config) (*Client, error) { 81 uid, err := uuid.FromString(config.UUID) 82 if err != nil { 83 return nil, err 84 } 85 86 if config.IsVless { 87 config.AlterID = 0 88 config.Security = "zero" 89 } 90 91 var security Security 92 switch config.Security { 93 case "aes-128-gcm": 94 security = SecurityAES128GCM 95 case "chacha20-poly1305": 96 security = SecurityCHACHA20POLY1305 97 case "none": 98 security = SecurityNone 99 case "zero": 100 security = SecurityZero 101 case "auto": 102 security = SecurityCHACHA20POLY1305 103 if runtime.GOARCH == "amd64" || runtime.GOARCH == "s390x" || runtime.GOARCH == "arm64" { 104 security = SecurityAES128GCM 105 } 106 default: 107 return nil, fmt.Errorf("unknown security type: %s", config.Security) 108 } 109 110 return &Client{ 111 user: newAlterIDs(newID(&uid), config.AlterID), 112 uuid: &uid, 113 security: security, 114 isAead: config.IsAead, 115 isVless: config.IsVless, 116 }, nil 117 }