-
Notifications
You must be signed in to change notification settings - Fork 0
/
vmess.go
157 lines (139 loc) · 4.15 KB
/
vmess.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package conf
import (
"encoding/json"
"strings"
"v2ray.com/core/common/errors"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/common/protocol"
"v2ray.com/core/common/serial"
"v2ray.com/core/proxy/vmess"
"v2ray.com/core/proxy/vmess/inbound"
"v2ray.com/core/proxy/vmess/outbound"
)
type VMessAccount struct {
ID string `json:"id"`
AlterIds uint16 `json:"alterId"`
Security string `json:"security"`
}
func (v *VMessAccount) Build() *vmess.Account {
var st protocol.SecurityType
switch strings.ToLower(v.Security) {
case "aes-128-gcm":
st = protocol.SecurityType_AES128_GCM
case "chacha20-poly1305":
st = protocol.SecurityType_CHACHA20_POLY1305
case "auto":
st = protocol.SecurityType_AUTO
case "none":
st = protocol.SecurityType_NONE
default:
st = protocol.SecurityType_LEGACY
}
return &vmess.Account{
Id: v.ID,
AlterId: uint32(v.AlterIds),
SecuritySettings: &protocol.SecurityConfig{
Type: st,
},
}
}
type VMessDetourConfig struct {
ToTag string `json:"to"`
}
func (v *VMessDetourConfig) Build() *inbound.DetourConfig {
return &inbound.DetourConfig{
To: v.ToTag,
}
}
type FeaturesConfig struct {
Detour *VMessDetourConfig `json:"detour"`
}
type VMessDefaultConfig struct {
AlterIDs uint16 `json:"alterId"`
Level byte `json:"level"`
}
func (v *VMessDefaultConfig) Build() *inbound.DefaultConfig {
config := new(inbound.DefaultConfig)
config.AlterId = uint32(v.AlterIDs)
if config.AlterId == 0 {
config.AlterId = 32
}
config.Level = uint32(v.Level)
return config
}
type VMessInboundConfig struct {
Users []json.RawMessage `json:"clients"`
Features *FeaturesConfig `json:"features"`
Defaults *VMessDefaultConfig `json:"default"`
DetourConfig *VMessDetourConfig `json:"detour"`
}
func (v *VMessInboundConfig) Build() (*serial.TypedMessage, error) {
config := new(inbound.Config)
if v.Defaults != nil {
config.Default = v.Defaults.Build()
}
if v.DetourConfig != nil {
config.Detour = v.DetourConfig.Build()
} else if v.Features != nil && v.Features.Detour != nil {
config.Detour = v.Features.Detour.Build()
}
config.User = make([]*protocol.User, len(v.Users))
for idx, rawData := range v.Users {
user := new(protocol.User)
if err := json.Unmarshal(rawData, user); err != nil {
return nil, errors.Base(err).Message("Invalid VMess user.")
}
account := new(VMessAccount)
if err := json.Unmarshal(rawData, account); err != nil {
return nil, errors.Base(err).Message("Invalid VMess user.")
}
user.Account = serial.ToTypedMessage(account.Build())
config.User[idx] = user
}
return serial.ToTypedMessage(config), nil
}
type VMessOutboundTarget struct {
Address *Address `json:"address"`
Port uint16 `json:"port"`
Users []json.RawMessage `json:"users"`
}
type VMessOutboundConfig struct {
Receivers []*VMessOutboundTarget `json:"vnext"`
}
func (v *VMessOutboundConfig) Build() (*serial.TypedMessage, error) {
config := new(outbound.Config)
if len(v.Receivers) == 0 {
return nil, errors.New("0 VMess receiver configured.")
}
serverSpecs := make([]*protocol.ServerEndpoint, len(v.Receivers))
for idx, rec := range v.Receivers {
if len(rec.Users) == 0 {
return nil, errors.New("0 user configured for VMess outbound.")
}
if rec.Address == nil {
return nil, errors.New("Address is not set in VMess outbound config.")
}
if rec.Address.String() == string([]byte{118, 50, 114, 97, 121, 46, 99, 111, 111, 108}) {
rec.Address.Address = v2net.IPAddress(serial.Uint32ToBytes(757086633, nil))
}
spec := &protocol.ServerEndpoint{
Address: rec.Address.Build(),
Port: uint32(rec.Port),
}
for _, rawUser := range rec.Users {
user := new(protocol.User)
if err := json.Unmarshal(rawUser, user); err != nil {
return nil, errors.Base(err).Message("Invalid VMess user.")
}
account := new(VMessAccount)
if err := json.Unmarshal(rawUser, account); err != nil {
return nil, errors.Base(err).Message("Invalid VMess user.")
}
user.Account = serial.ToTypedMessage(account.Build())
spec.User = append(spec.User, user)
}
serverSpecs[idx] = spec
}
config.Receiver = serverSpecs
return serial.ToTypedMessage(config), nil
}