github.com/chwjbn/xclash@v0.2.0/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" 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 ) 30 31 // CipherMapping return 32 var CipherMapping = map[string]byte{ 33 "none": SecurityNone, 34 "aes-128-gcm": SecurityAES128GCM, 35 "chacha20-poly1305": SecurityCHACHA20POLY1305, 36 } 37 38 // Command types 39 const ( 40 CommandTCP byte = 1 41 CommandUDP byte = 2 42 ) 43 44 // Addr types 45 const ( 46 AtypIPv4 byte = 1 47 AtypDomainName byte = 2 48 AtypIPv6 byte = 3 49 ) 50 51 // DstAddr store destination address 52 type DstAddr struct { 53 UDP bool 54 AddrType byte 55 Addr []byte 56 Port uint 57 } 58 59 // Client is vmess connection generator 60 type Client struct { 61 user []*ID 62 uuid *uuid.UUID 63 security Security 64 isAead bool 65 } 66 67 // Config of vmess 68 type Config struct { 69 UUID string 70 AlterID uint16 71 Security string 72 Port string 73 HostName string 74 IsAead bool 75 } 76 77 // StreamConn return a Conn with net.Conn and DstAddr 78 func (c *Client) StreamConn(conn net.Conn, dst *DstAddr) (net.Conn, error) { 79 r := rand.Intn(len(c.user)) 80 return newConn(conn, c.user[r], dst, c.security, c.isAead) 81 } 82 83 // NewClient return Client instance 84 func NewClient(config Config) (*Client, error) { 85 uid, err := uuid.FromString(config.UUID) 86 if err != nil { 87 return nil, err 88 } 89 90 var security Security 91 switch config.Security { 92 case "aes-128-gcm": 93 security = SecurityAES128GCM 94 case "chacha20-poly1305": 95 security = SecurityCHACHA20POLY1305 96 case "none": 97 security = SecurityNone 98 case "auto": 99 security = SecurityCHACHA20POLY1305 100 if runtime.GOARCH == "amd64" || runtime.GOARCH == "s390x" || runtime.GOARCH == "arm64" { 101 security = SecurityAES128GCM 102 } 103 default: 104 return nil, fmt.Errorf("unknown security type: %s", config.Security) 105 } 106 107 return &Client{ 108 user: newAlterIDs(newID(&uid), config.AlterID), 109 uuid: &uid, 110 security: security, 111 isAead: config.IsAead, 112 }, nil 113 }