1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-07-01 11:35:23 +00:00
v2fly/infra/conf/vless.go
2020-08-03 06:13:26 +00:00

176 lines
4.8 KiB
Go

package conf
import (
"encoding/json"
"github.com/golang/protobuf/proto"
"v2ray.com/core/common/net"
"v2ray.com/core/common/protocol"
"v2ray.com/core/common/serial"
"v2ray.com/core/proxy/vless"
"v2ray.com/core/proxy/vless/inbound"
"v2ray.com/core/proxy/vless/outbound"
)
type VLessInboundFallback struct {
Addr *Address `json:"addr"`
Port uint16 `json:"port"`
Unix string `json:"unix"`
Xver uint16 `json:"xver"`
}
type VLessInboundConfig struct {
Users []json.RawMessage `json:"clients"`
Decryption string `json:"decryption"`
Fallback *VLessInboundFallback `json:"fallback"`
Fallback_h2 *VLessInboundFallback `json:"fallback_h2"`
}
// Build implements Buildable
func (c *VLessInboundConfig) Build() (proto.Message, error) {
config := new(inbound.Config)
if c.Decryption != "none" {
return nil, newError(`please add/set "decryption":"none" directly to every VLESS "settings"`)
}
config.Decryption = c.Decryption
if c.Fallback != nil {
if c.Fallback.Xver > 2 {
return nil, newError(`VLESS "fallback": invalid PROXY protocol version, "xver" only accepts 0, 1, 2`)
}
if c.Fallback.Unix != "" {
if c.Fallback.Unix[0] == '@' {
c.Fallback.Unix = "\x00" + c.Fallback.Unix[1:]
}
} else {
if c.Fallback.Port == 0 {
return nil, newError(`please fill in a valid value for "port" in VLESS "fallback"`)
}
}
if c.Fallback.Addr == nil {
c.Fallback.Addr = &Address{
Address: net.ParseAddress("127.0.0.1"),
}
}
config.Fallback = &inbound.Fallback{
Addr: c.Fallback.Addr.Build(),
Port: uint32(c.Fallback.Port),
Unix: c.Fallback.Unix,
Xver: uint32(c.Fallback.Xver),
}
}
if c.Fallback_h2 != nil {
if config.Fallback == nil {
return nil, newError(`VLESS "fallback_h2" can't exist alone without "fallback"`)
}
if c.Fallback_h2.Xver > 2 {
return nil, newError(`VLESS "fallback_h2": invalid PROXY protocol version, "xver" only accepts 0, 1, 2`)
}
if c.Fallback_h2.Unix != "" {
if c.Fallback_h2.Unix[0] == '@' {
c.Fallback_h2.Unix = "\x00" + c.Fallback_h2.Unix[1:]
}
} else {
if c.Fallback_h2.Port == 0 {
return nil, newError(`please fill in a valid value for "port" in VLESS "fallback_h2"`)
}
}
if c.Fallback_h2.Addr == nil {
c.Fallback_h2.Addr = &Address{
Address: net.ParseAddress("127.0.0.1"),
}
}
config.FallbackH2 = &inbound.FallbackH2{
Addr: c.Fallback_h2.Addr.Build(),
Port: uint32(c.Fallback_h2.Port),
Unix: c.Fallback_h2.Unix,
Xver: uint32(c.Fallback_h2.Xver),
}
}
config.User = make([]*protocol.User, len(c.Users))
for idx, rawData := range c.Users {
user := new(protocol.User)
if err := json.Unmarshal(rawData, user); err != nil {
return nil, newError("invalid VLESS user").Base(err)
}
account := new(vless.Account)
if err := json.Unmarshal(rawData, account); err != nil {
return nil, newError("invalid VLESS user").Base(err)
}
if account.Schedulers != "" {
return nil, newError(`VLESS attr "schedulers" is not available in this version`)
}
if account.Encryption != "" {
return nil, newError(`VLESS attr "encryption" should not in inbound settings`)
}
user.Account = serial.ToTypedMessage(account)
config.User[idx] = user
}
return config, nil
}
type VLessOutboundTarget struct {
Address *Address `json:"address"`
Port uint16 `json:"port"`
Users []json.RawMessage `json:"users"`
}
type VLessOutboundConfig struct {
Receivers []*VLessOutboundTarget `json:"vnext"`
}
// Build implements Buildable
func (c *VLessOutboundConfig) Build() (proto.Message, error) {
config := new(outbound.Config)
if len(c.Receivers) == 0 {
return nil, newError("0 VLESS receiver configured")
}
serverSpecs := make([]*protocol.ServerEndpoint, len(c.Receivers))
for idx, rec := range c.Receivers {
if len(rec.Users) == 0 {
return nil, newError("0 user configured for VLESS outbound")
}
if rec.Address == nil {
return nil, newError("address is not set in VLESS outbound config")
}
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, newError("invalid VLESS user").Base(err)
}
account := new(vless.Account)
if err := json.Unmarshal(rawUser, account); err != nil {
return nil, newError("invalid VLESS user").Base(err)
}
if account.Schedulers != "" {
return nil, newError(`VLESS attr "schedulers" is not available in this version`)
}
if account.Encryption != "none" {
return nil, newError(`please add/set "encryption":"none" for every VLESS user in "users"`)
}
user.Account = serial.ToTypedMessage(account)
spec.User = append(spec.User, user)
}
serverSpecs[idx] = spec
}
config.Receiver = serverSpecs
return config, nil
}