github.com/eagleql/xray-core@v1.4.4/infra/conf/common.go (about) 1 package conf 2 3 import ( 4 "encoding/json" 5 "os" 6 "strings" 7 8 "github.com/eagleql/xray-core/common/net" 9 "github.com/eagleql/xray-core/common/protocol" 10 ) 11 12 type StringList []string 13 14 func NewStringList(raw []string) *StringList { 15 list := StringList(raw) 16 return &list 17 } 18 19 func (v StringList) Len() int { 20 return len(v) 21 } 22 23 func (v *StringList) UnmarshalJSON(data []byte) error { 24 var strarray []string 25 if err := json.Unmarshal(data, &strarray); err == nil { 26 *v = *NewStringList(strarray) 27 return nil 28 } 29 30 var rawstr string 31 if err := json.Unmarshal(data, &rawstr); err == nil { 32 strlist := strings.Split(rawstr, ",") 33 *v = *NewStringList(strlist) 34 return nil 35 } 36 return newError("unknown format of a string list: " + string(data)) 37 } 38 39 type Address struct { 40 net.Address 41 } 42 43 func (v *Address) UnmarshalJSON(data []byte) error { 44 var rawStr string 45 if err := json.Unmarshal(data, &rawStr); err != nil { 46 return newError("invalid address: ", string(data)).Base(err) 47 } 48 v.Address = net.ParseAddress(rawStr) 49 50 return nil 51 } 52 53 func (v *Address) Build() *net.IPOrDomain { 54 return net.NewIPOrDomain(v.Address) 55 } 56 57 type Network string 58 59 func (v Network) Build() net.Network { 60 switch strings.ToLower(string(v)) { 61 case "tcp": 62 return net.Network_TCP 63 case "udp": 64 return net.Network_UDP 65 case "unix": 66 return net.Network_UNIX 67 default: 68 return net.Network_Unknown 69 } 70 } 71 72 type NetworkList []Network 73 74 func (v *NetworkList) UnmarshalJSON(data []byte) error { 75 var strarray []Network 76 if err := json.Unmarshal(data, &strarray); err == nil { 77 nl := NetworkList(strarray) 78 *v = nl 79 return nil 80 } 81 82 var rawstr Network 83 if err := json.Unmarshal(data, &rawstr); err == nil { 84 strlist := strings.Split(string(rawstr), ",") 85 nl := make([]Network, len(strlist)) 86 for idx, network := range strlist { 87 nl[idx] = Network(network) 88 } 89 *v = nl 90 return nil 91 } 92 return newError("unknown format of a string list: " + string(data)) 93 } 94 95 func (v *NetworkList) Build() []net.Network { 96 if v == nil { 97 return []net.Network{net.Network_TCP} 98 } 99 100 list := make([]net.Network, 0, len(*v)) 101 for _, network := range *v { 102 list = append(list, network.Build()) 103 } 104 return list 105 } 106 107 func parseIntPort(data []byte) (net.Port, error) { 108 var intPort uint32 109 err := json.Unmarshal(data, &intPort) 110 if err != nil { 111 return net.Port(0), err 112 } 113 return net.PortFromInt(intPort) 114 } 115 116 func parseStringPort(s string) (net.Port, net.Port, error) { 117 if strings.HasPrefix(s, "env:") { 118 s = s[4:] 119 s = os.Getenv(s) 120 } 121 122 pair := strings.SplitN(s, "-", 2) 123 if len(pair) == 0 { 124 return net.Port(0), net.Port(0), newError("invalid port range: ", s) 125 } 126 if len(pair) == 1 { 127 port, err := net.PortFromString(pair[0]) 128 return port, port, err 129 } 130 131 fromPort, err := net.PortFromString(pair[0]) 132 if err != nil { 133 return net.Port(0), net.Port(0), err 134 } 135 toPort, err := net.PortFromString(pair[1]) 136 if err != nil { 137 return net.Port(0), net.Port(0), err 138 } 139 return fromPort, toPort, nil 140 } 141 142 func parseJSONStringPort(data []byte) (net.Port, net.Port, error) { 143 var s string 144 err := json.Unmarshal(data, &s) 145 if err != nil { 146 return net.Port(0), net.Port(0), err 147 } 148 return parseStringPort(s) 149 } 150 151 type PortRange struct { 152 From uint32 153 To uint32 154 } 155 156 func (v *PortRange) Build() *net.PortRange { 157 return &net.PortRange{ 158 From: v.From, 159 To: v.To, 160 } 161 } 162 163 // UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON 164 func (v *PortRange) UnmarshalJSON(data []byte) error { 165 port, err := parseIntPort(data) 166 if err == nil { 167 v.From = uint32(port) 168 v.To = uint32(port) 169 return nil 170 } 171 172 from, to, err := parseJSONStringPort(data) 173 if err == nil { 174 v.From = uint32(from) 175 v.To = uint32(to) 176 if v.From > v.To { 177 return newError("invalid port range ", v.From, " -> ", v.To) 178 } 179 return nil 180 } 181 182 return newError("invalid port range: ", string(data)) 183 } 184 185 type PortList struct { 186 Range []PortRange 187 } 188 189 func (list *PortList) Build() *net.PortList { 190 portList := new(net.PortList) 191 for _, r := range list.Range { 192 portList.Range = append(portList.Range, r.Build()) 193 } 194 return portList 195 } 196 197 // UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON 198 func (list *PortList) UnmarshalJSON(data []byte) error { 199 var listStr string 200 var number uint32 201 if err := json.Unmarshal(data, &listStr); err != nil { 202 if err2 := json.Unmarshal(data, &number); err2 != nil { 203 return newError("invalid port: ", string(data)).Base(err2) 204 } 205 } 206 rangelist := strings.Split(listStr, ",") 207 for _, rangeStr := range rangelist { 208 trimmed := strings.TrimSpace(rangeStr) 209 if len(trimmed) > 0 { 210 if strings.Contains(trimmed, "-") { 211 from, to, err := parseStringPort(trimmed) 212 if err != nil { 213 return newError("invalid port range: ", trimmed).Base(err) 214 } 215 list.Range = append(list.Range, PortRange{From: uint32(from), To: uint32(to)}) 216 } else { 217 port, err := parseIntPort([]byte(trimmed)) 218 if err != nil { 219 return newError("invalid port: ", trimmed).Base(err) 220 } 221 list.Range = append(list.Range, PortRange{From: uint32(port), To: uint32(port)}) 222 } 223 } 224 } 225 if number != 0 { 226 list.Range = append(list.Range, PortRange{From: number, To: number}) 227 } 228 return nil 229 } 230 231 type User struct { 232 EmailString string `json:"email"` 233 LevelByte byte `json:"level"` 234 } 235 236 func (v *User) Build() *protocol.User { 237 return &protocol.User{ 238 Email: v.EmailString, 239 Level: uint32(v.LevelByte), 240 } 241 }