mirror of
https://github.com/v2ray/v2ray-core.git
synced 2026-11-12 22:42:18 +00:00
Refactor vmess config
This commit is contained in:
1 parent
f10f08c87d
commit
771d0225c7
18 files changed
+263
-184
No files matched your search
@@ -0,0 +1,78 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
|
||||
"github.com/v2ray/v2ray-core/common/log"
|
||||
)
|
||||
|
||||
const (
|
||||
IDBytesLen = 16
|
||||
)
|
||||
|
||||
var (
|
||||
InvalidID = errors.New("Invalid ID.")
|
||||
)
|
||||
|
||||
// The ID of en entity, in the form of an UUID.
|
||||
type ID struct {
|
||||
String string
|
||||
Bytes [IDBytesLen]byte
|
||||
cmdKey [IDBytesLen]byte
|
||||
}
|
||||
|
||||
func NewID(id string) (*ID, error) {
|
||||
idBytes, err := UUIDToID(id)
|
||||
if err != nil {
|
||||
log.Error("Failed to parse id %s", id)
|
||||
return &ID{}, InvalidID
|
||||
}
|
||||
|
||||
md5hash := md5.New()
|
||||
md5hash.Write(idBytes[:])
|
||||
md5hash.Write([]byte("c48619fe-8f02-49e0-b9e9-edf763e17e21"))
|
||||
cmdKey := md5.Sum(nil)
|
||||
|
||||
return &ID{
|
||||
String: id,
|
||||
Bytes: idBytes,
|
||||
cmdKey: cmdKey,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (v ID) CmdKey() []byte {
|
||||
return v.cmdKey[:]
|
||||
}
|
||||
|
||||
var byteGroups = []int{8, 4, 4, 4, 12}
|
||||
|
||||
// TODO: leverage a full functional UUID library
|
||||
func UUIDToID(uuid string) (v [IDBytesLen]byte, err error) {
|
||||
text := []byte(uuid)
|
||||
if len(text) < 32 {
|
||||
log.Error("uuid: invalid UUID string: %s", text)
|
||||
err = InvalidID
|
||||
return
|
||||
}
|
||||
|
||||
b := v[:]
|
||||
|
||||
for _, byteGroup := range byteGroups {
|
||||
if text[0] == '-' {
|
||||
text = text[1:]
|
||||
}
|
||||
|
||||
_, err = hex.Decode(b[:byteGroup/2], text[:byteGroup])
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
text = text[byteGroup:]
|
||||
b = b[byteGroup/2:]
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/v2ray/v2ray-core/testing/unit"
|
||||
)
|
||||
|
||||
func TestUUIDToID(t *testing.T) {
|
||||
assert := unit.Assert(t)
|
||||
|
||||
uuid := "2418d087-648d-4990-86e8-19dca1d006d3"
|
||||
expectedBytes := []byte{0x24, 0x18, 0xd0, 0x87, 0x64, 0x8d, 0x49, 0x90, 0x86, 0xe8, 0x19, 0xdc, 0xa1, 0xd0, 0x06, 0xd3}
|
||||
|
||||
actualBytes, _ := NewID(uuid)
|
||||
assert.Bytes(actualBytes.Bytes[:]).Named("UUID").Equals(expectedBytes)
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package config
|
||||
|
||||
type Inbound interface {
|
||||
AllowedUsers() []User
|
||||
UDPEnabled() bool
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"github.com/v2ray/v2ray-core/config"
|
||||
"github.com/v2ray/v2ray-core/config/json"
|
||||
vmessconfig "github.com/v2ray/v2ray-core/proxy/vmess/config"
|
||||
)
|
||||
|
||||
type Inbound struct {
|
||||
AllowedClients []*ConfigUser `json:"clients"`
|
||||
UDP bool `json:"udp"`
|
||||
}
|
||||
|
||||
func (c *Inbound) AllowedUsers() []vmessconfig.User {
|
||||
users := make([]vmessconfig.User, 0, len(c.AllowedClients))
|
||||
for _, rawUser := range c.AllowedClients {
|
||||
users = append(users, rawUser)
|
||||
}
|
||||
return users
|
||||
}
|
||||
|
||||
func (c *Inbound) UDPEnabled() bool {
|
||||
return c.UDP
|
||||
}
|
||||
|
||||
func init() {
|
||||
json.RegisterConfigType("vmess", config.TypeInbound, func() interface{} {
|
||||
return new(Inbound)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/v2ray/v2ray-core/common/log"
|
||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||
"github.com/v2ray/v2ray-core/config"
|
||||
jsonconfig "github.com/v2ray/v2ray-core/config/json"
|
||||
vmessconfig "github.com/v2ray/v2ray-core/proxy/vmess/config"
|
||||
)
|
||||
|
||||
type RawConfigTarget struct {
|
||||
Address string `json:"address"`
|
||||
Port uint16 `json:"port"`
|
||||
Users []*ConfigUser `json:"users"`
|
||||
Network string `json:"network"`
|
||||
}
|
||||
|
||||
func (config RawConfigTarget) HasNetwork(network string) bool {
|
||||
return strings.Contains(config.Network, network)
|
||||
}
|
||||
|
||||
type ConfigTarget struct {
|
||||
Address v2net.Address
|
||||
Users []*ConfigUser
|
||||
TCPEnabled bool
|
||||
UDPEnabled bool
|
||||
}
|
||||
|
||||
func (t *ConfigTarget) UnmarshalJSON(data []byte) error {
|
||||
var rawConfig RawConfigTarget
|
||||
if err := json.Unmarshal(data, &rawConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
ip := net.ParseIP(rawConfig.Address)
|
||||
if ip == nil {
|
||||
log.Error("Unable to parse IP: %s", rawConfig.Address)
|
||||
return config.BadConfiguration
|
||||
}
|
||||
t.Address = v2net.IPAddress(ip, rawConfig.Port)
|
||||
if rawConfig.HasNetwork("tcp") {
|
||||
t.TCPEnabled = true
|
||||
}
|
||||
if rawConfig.HasNetwork("udp") {
|
||||
t.UDPEnabled = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Outbound struct {
|
||||
TargetList []*ConfigTarget `json:"vnext"`
|
||||
}
|
||||
|
||||
func (o *Outbound) Targets() []*vmessconfig.OutboundTarget {
|
||||
targets := make([]*vmessconfig.OutboundTarget, 0, 2*len(o.TargetList))
|
||||
for _, rawTarget := range o.TargetList {
|
||||
users := make([]vmessconfig.User, 0, len(rawTarget.Users))
|
||||
for _, rawUser := range rawTarget.Users {
|
||||
users = append(users, rawUser)
|
||||
}
|
||||
if rawTarget.TCPEnabled {
|
||||
targets = append(targets, &vmessconfig.OutboundTarget{
|
||||
Destination: v2net.NewTCPDestination(rawTarget.Address),
|
||||
Accounts: users,
|
||||
})
|
||||
}
|
||||
if rawTarget.UDPEnabled {
|
||||
targets = append(targets, &vmessconfig.OutboundTarget{
|
||||
Destination: v2net.NewUDPDestination(rawTarget.Address),
|
||||
Accounts: users,
|
||||
})
|
||||
}
|
||||
}
|
||||
return targets
|
||||
}
|
||||
|
||||
func init() {
|
||||
jsonconfig.RegisterConfigType("vmess", config.TypeOutbound, func() interface{} {
|
||||
return new(Outbound)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/config"
|
||||
)
|
||||
|
||||
// ConfigUser is an user account in VMess configuration.
|
||||
type ConfigUser struct {
|
||||
Id *config.ID
|
||||
Email string
|
||||
}
|
||||
|
||||
func (u *ConfigUser) UnmarshalJSON(data []byte) error {
|
||||
type rawUser struct {
|
||||
IdString string `json:"id"`
|
||||
EmailString string `json:"email"`
|
||||
}
|
||||
var rawUserValue rawUser
|
||||
if err := json.Unmarshal(data, &rawUserValue); err != nil {
|
||||
return err
|
||||
}
|
||||
id, err := config.NewID(rawUserValue.IdString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.Id = id
|
||||
u.Email = rawUserValue.EmailString
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *ConfigUser) ID() *config.ID {
|
||||
return u.Id
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||
)
|
||||
|
||||
type OutboundTarget struct {
|
||||
Destination v2net.Destination
|
||||
Accounts []User
|
||||
}
|
||||
|
||||
type Outbound interface {
|
||||
Targets() []*OutboundTarget
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package config
|
||||
|
||||
type User interface {
|
||||
ID() *ID
|
||||
}
|
||||
Reference in new issue
Block a user