github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/infra/conf/vless.go (about) 1 package conf 2 3 import ( 4 "encoding/json" 5 "runtime" 6 "strconv" 7 "syscall" 8 9 "github.com/golang/protobuf/proto" 10 11 "v2ray.com/core/common/net" 12 "v2ray.com/core/common/protocol" 13 "v2ray.com/core/common/serial" 14 "v2ray.com/core/proxy/vless" 15 "v2ray.com/core/proxy/vless/inbound" 16 "v2ray.com/core/proxy/vless/outbound" 17 ) 18 19 type VLessInboundFallback struct { 20 Alpn string `json:"alpn"` 21 Path string `json:"path"` 22 Type string `json:"type"` 23 Dest json.RawMessage `json:"dest"` 24 Xver uint64 `json:"xver"` 25 } 26 27 type VLessInboundConfig struct { 28 Clients []json.RawMessage `json:"clients"` 29 Decryption string `json:"decryption"` 30 Fallback json.RawMessage `json:"fallback"` 31 Fallbacks []*VLessInboundFallback `json:"fallbacks"` 32 } 33 34 // Build implements Buildable 35 func (c *VLessInboundConfig) Build() (proto.Message, error) { 36 37 config := new(inbound.Config) 38 39 if len(c.Clients) == 0 { 40 //return nil, newError(`VLESS settings: "clients" is empty`) 41 } 42 config.Clients = make([]*protocol.User, len(c.Clients)) 43 for idx, rawUser := range c.Clients { 44 user := new(protocol.User) 45 if err := json.Unmarshal(rawUser, user); err != nil { 46 return nil, newError(`VLESS clients: invalid user`).Base(err) 47 } 48 account := new(vless.Account) 49 if err := json.Unmarshal(rawUser, account); err != nil { 50 return nil, newError(`VLESS clients: invalid user`).Base(err) 51 } 52 53 switch account.Flow { 54 case "", "xtls-rprx-origin", "xtls-rprx-direct": 55 default: 56 return nil, newError(`VLESS clients: "flow" doesn't support "` + account.Flow + `" in this version`) 57 } 58 59 if account.Encryption != "" { 60 return nil, newError(`VLESS clients: "encryption" should not in inbound settings`) 61 } 62 63 user.Account = serial.ToTypedMessage(account) 64 config.Clients[idx] = user 65 } 66 67 if c.Decryption != "none" { 68 return nil, newError(`VLESS settings: please add/set "decryption":"none" to every settings`) 69 } 70 config.Decryption = c.Decryption 71 72 if c.Fallback != nil { 73 return nil, newError(`VLESS settings: please use "fallbacks":[{}] instead of "fallback":{}`) 74 } 75 for _, fb := range c.Fallbacks { 76 var i uint16 77 var s string 78 if err := json.Unmarshal(fb.Dest, &i); err == nil { 79 s = strconv.Itoa(int(i)) 80 } else { 81 _ = json.Unmarshal(fb.Dest, &s) 82 } 83 config.Fallbacks = append(config.Fallbacks, &inbound.Fallback{ 84 Alpn: fb.Alpn, 85 Path: fb.Path, 86 Type: fb.Type, 87 Dest: s, 88 Xver: fb.Xver, 89 }) 90 } 91 for _, fb := range config.Fallbacks { 92 /* 93 if fb.Alpn == "h2" && fb.Path != "" { 94 return nil, newError(`VLESS fallbacks: "alpn":"h2" doesn't support "path"`) 95 } 96 */ 97 if fb.Path != "" && fb.Path[0] != '/' { 98 return nil, newError(`VLESS fallbacks: "path" must be empty or start with "/"`) 99 } 100 if fb.Type == "" && fb.Dest != "" { 101 if fb.Dest == "serve-ws-none" { 102 fb.Type = "serve" 103 } else { 104 switch fb.Dest[0] { 105 case '@', '/': 106 fb.Type = "unix" 107 if fb.Dest[0] == '@' && len(fb.Dest) > 1 && fb.Dest[1] == '@' && runtime.GOOS == "linux" { 108 fullAddr := make([]byte, len(syscall.RawSockaddrUnix{}.Path)) // may need padding to work in front of haproxy 109 copy(fullAddr, fb.Dest[1:]) 110 fb.Dest = string(fullAddr) 111 } 112 default: 113 if _, err := strconv.Atoi(fb.Dest); err == nil { 114 fb.Dest = "127.0.0.1:" + fb.Dest 115 } 116 if _, _, err := net.SplitHostPort(fb.Dest); err == nil { 117 fb.Type = "tcp" 118 } 119 } 120 } 121 } 122 if fb.Type == "" { 123 return nil, newError(`VLESS fallbacks: please fill in a valid value for every "dest"`) 124 } 125 if fb.Xver > 2 { 126 return nil, newError(`VLESS fallbacks: invalid PROXY protocol version, "xver" only accepts 0, 1, 2`) 127 } 128 } 129 130 return config, nil 131 } 132 133 type VLessOutboundVnext struct { 134 Address *Address `json:"address"` 135 Port uint16 `json:"port"` 136 Users []json.RawMessage `json:"users"` 137 } 138 139 type VLessOutboundConfig struct { 140 Vnext []*VLessOutboundVnext `json:"vnext"` 141 } 142 143 // Build implements Buildable 144 func (c *VLessOutboundConfig) Build() (proto.Message, error) { 145 146 config := new(outbound.Config) 147 148 if len(c.Vnext) == 0 { 149 return nil, newError(`VLESS settings: "vnext" is empty`) 150 } 151 config.Vnext = make([]*protocol.ServerEndpoint, len(c.Vnext)) 152 for idx, rec := range c.Vnext { 153 if rec.Address == nil { 154 return nil, newError(`VLESS vnext: "address" is not set`) 155 } 156 if len(rec.Users) == 0 { 157 return nil, newError(`VLESS vnext: "users" is empty`) 158 } 159 spec := &protocol.ServerEndpoint{ 160 Address: rec.Address.Build(), 161 Port: uint32(rec.Port), 162 User: make([]*protocol.User, len(rec.Users)), 163 } 164 for idx, rawUser := range rec.Users { 165 user := new(protocol.User) 166 if err := json.Unmarshal(rawUser, user); err != nil { 167 return nil, newError(`VLESS users: invalid user`).Base(err) 168 } 169 account := new(vless.Account) 170 if err := json.Unmarshal(rawUser, account); err != nil { 171 return nil, newError(`VLESS users: invalid user`).Base(err) 172 } 173 174 switch account.Flow { 175 case "", "xtls-rprx-origin", "xtls-rprx-origin-udp443", "xtls-rprx-direct", "xtls-rprx-direct-udp443": 176 default: 177 return nil, newError(`VLESS users: "flow" doesn't support "` + account.Flow + `" in this version`) 178 } 179 180 if account.Encryption != "none" { 181 return nil, newError(`VLESS users: please add/set "encryption":"none" for every user`) 182 } 183 184 user.Account = serial.ToTypedMessage(account) 185 spec.User[idx] = user 186 } 187 config.Vnext[idx] = spec 188 } 189 190 return config, nil 191 }