Clash.Meta/transport/vmess/vmess.go

115 lines
2.2 KiB
Go
Raw Normal View History

2018-09-06 10:53:29 +08:00
package vmess
import (
"fmt"
"github.com/Dreamacro/clash/common/utils"
2018-09-06 10:53:29 +08:00
"math/rand"
"net"
"runtime"
"github.com/gofrs/uuid"
)
// Version of vmess
const Version byte = 1
// Request Options
const (
OptionChunkStream byte = 1
OptionChunkMasking byte = 4
)
// Security type vmess
type Security = byte
// Cipher types
const (
SecurityAES128GCM Security = 3
SecurityCHACHA20POLY1305 Security = 4
SecurityNone Security = 5
)
// CipherMapping return
var CipherMapping = map[string]byte{
"none": SecurityNone,
"aes-128-gcm": SecurityAES128GCM,
"chacha20-poly1305": SecurityCHACHA20POLY1305,
}
// Command types
const (
CommandTCP byte = 1
CommandUDP byte = 2
)
// Addr types
const (
AtypIPv4 byte = 1
AtypDomainName byte = 2
AtypIPv6 byte = 3
)
// DstAddr store destination address
type DstAddr struct {
2019-04-25 16:32:15 +08:00
UDP bool
2018-09-06 10:53:29 +08:00
AddrType byte
Addr []byte
Port uint
}
// Client is vmess connection generator
type Client struct {
user []*ID
uuid *uuid.UUID
security Security
2021-03-30 17:34:16 +08:00
isAead bool
2018-09-06 10:53:29 +08:00
}
// Config of vmess
type Config struct {
UUID string
AlterID uint16
Security string
Port string
HostName string
2021-03-30 17:34:16 +08:00
IsAead bool
2018-09-06 10:53:29 +08:00
}
// StreamConn return a Conn with net.Conn and DstAddr
func (c *Client) StreamConn(conn net.Conn, dst *DstAddr) (net.Conn, error) {
2018-09-06 10:53:29 +08:00
r := rand.Intn(len(c.user))
2021-03-30 17:34:16 +08:00
return newConn(conn, c.user[r], dst, c.security, c.isAead)
2018-09-06 10:53:29 +08:00
}
// NewClient return Client instance
func NewClient(config Config) (*Client, error) {
uid, err := utils.UUIDMap(config.UUID)
2018-09-06 10:53:29 +08:00
if err != nil {
return nil, err
}
var security Security
switch config.Security {
case "aes-128-gcm":
security = SecurityAES128GCM
case "chacha20-poly1305":
security = SecurityCHACHA20POLY1305
case "none":
security = SecurityNone
case "auto":
security = SecurityCHACHA20POLY1305
if runtime.GOARCH == "amd64" || runtime.GOARCH == "s390x" || runtime.GOARCH == "arm64" {
security = SecurityAES128GCM
}
default:
2020-08-25 22:19:59 +08:00
return nil, fmt.Errorf("unknown security type: %s", config.Security)
2018-09-06 10:53:29 +08:00
}
2018-10-28 23:46:32 +08:00
2018-09-06 10:53:29 +08:00
return &Client{
user: newAlterIDs(newID(&uid), config.AlterID),
uuid: &uid,
security: security,
2021-03-30 17:34:16 +08:00
isAead: config.IsAead,
2018-09-06 10:53:29 +08:00
}, nil
}