github.com/imannamdari/v2ray-core/v5@v5.0.5/infra/conf/v4/vmess.go (about)

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