common.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. package conf
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "strconv"
  6. "strings"
  7. "github.com/xtls/xray-core/common/errors"
  8. "github.com/xtls/xray-core/common/net"
  9. "github.com/xtls/xray-core/common/platform"
  10. "github.com/xtls/xray-core/common/protocol"
  11. )
  12. type StringList []string
  13. func NewStringList(raw []string) *StringList {
  14. list := StringList(raw)
  15. return &list
  16. }
  17. func (v StringList) Len() int {
  18. return len(v)
  19. }
  20. func (v *StringList) UnmarshalJSON(data []byte) error {
  21. var strarray []string
  22. if err := json.Unmarshal(data, &strarray); err == nil {
  23. *v = *NewStringList(strarray)
  24. return nil
  25. }
  26. var rawstr string
  27. if err := json.Unmarshal(data, &rawstr); err == nil {
  28. strlist := strings.Split(rawstr, ",")
  29. *v = *NewStringList(strlist)
  30. return nil
  31. }
  32. return errors.New("unknown format of a string list: " + string(data))
  33. }
  34. type Address struct {
  35. net.Address
  36. }
  37. func (v Address) MarshalJSON() ([]byte, error) {
  38. return json.Marshal(v.Address.String())
  39. }
  40. func (v *Address) UnmarshalJSON(data []byte) error {
  41. var rawStr string
  42. if err := json.Unmarshal(data, &rawStr); err != nil {
  43. return errors.New("invalid address: ", string(data)).Base(err)
  44. }
  45. if strings.HasPrefix(rawStr, "env:") {
  46. rawStr = platform.NewEnvFlag(rawStr[4:]).GetValue(func() string { return "" })
  47. }
  48. v.Address = net.ParseAddress(rawStr)
  49. return nil
  50. }
  51. func (v *Address) Build() *net.IPOrDomain {
  52. return net.NewIPOrDomain(v.Address)
  53. }
  54. type Network string
  55. func (v Network) Build() net.Network {
  56. switch strings.ToLower(string(v)) {
  57. case "tcp":
  58. return net.Network_TCP
  59. case "udp":
  60. return net.Network_UDP
  61. case "unix":
  62. return net.Network_UNIX
  63. default:
  64. return net.Network_Unknown
  65. }
  66. }
  67. type NetworkList []Network
  68. func (v *NetworkList) UnmarshalJSON(data []byte) error {
  69. var strarray []Network
  70. if err := json.Unmarshal(data, &strarray); err == nil {
  71. nl := NetworkList(strarray)
  72. *v = nl
  73. return nil
  74. }
  75. var rawstr Network
  76. if err := json.Unmarshal(data, &rawstr); err == nil {
  77. strlist := strings.Split(string(rawstr), ",")
  78. nl := make([]Network, len(strlist))
  79. for idx, network := range strlist {
  80. nl[idx] = Network(network)
  81. }
  82. *v = nl
  83. return nil
  84. }
  85. return errors.New("unknown format of a string list: " + string(data))
  86. }
  87. func (v *NetworkList) Build() []net.Network {
  88. if v == nil {
  89. return []net.Network{net.Network_TCP}
  90. }
  91. list := make([]net.Network, 0, len(*v))
  92. for _, network := range *v {
  93. list = append(list, network.Build())
  94. }
  95. return list
  96. }
  97. func parseIntPort(data []byte) (net.Port, error) {
  98. var intPort uint32
  99. err := json.Unmarshal(data, &intPort)
  100. if err != nil {
  101. return net.Port(0), err
  102. }
  103. return net.PortFromInt(intPort)
  104. }
  105. func parseStringPort(s string) (net.Port, net.Port, error) {
  106. if strings.HasPrefix(s, "env:") {
  107. s = platform.NewEnvFlag(s[4:]).GetValue(func() string { return "" })
  108. }
  109. pair := strings.SplitN(s, "-", 2)
  110. if len(pair) == 0 {
  111. return net.Port(0), net.Port(0), errors.New("invalid port range: ", s)
  112. }
  113. if len(pair) == 1 {
  114. port, err := net.PortFromString(pair[0])
  115. return port, port, err
  116. }
  117. fromPort, err := net.PortFromString(pair[0])
  118. if err != nil {
  119. return net.Port(0), net.Port(0), err
  120. }
  121. toPort, err := net.PortFromString(pair[1])
  122. if err != nil {
  123. return net.Port(0), net.Port(0), err
  124. }
  125. return fromPort, toPort, nil
  126. }
  127. func parseJSONStringPort(data []byte) (net.Port, net.Port, error) {
  128. var s string
  129. err := json.Unmarshal(data, &s)
  130. if err != nil {
  131. return net.Port(0), net.Port(0), err
  132. }
  133. return parseStringPort(s)
  134. }
  135. type PortRange struct {
  136. From uint32
  137. To uint32
  138. }
  139. func (v *PortRange) Build() *net.PortRange {
  140. return &net.PortRange{
  141. From: v.From,
  142. To: v.To,
  143. }
  144. }
  145. // UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON
  146. func (v *PortRange) UnmarshalJSON(data []byte) error {
  147. port, err := parseIntPort(data)
  148. if err == nil {
  149. v.From = uint32(port)
  150. v.To = uint32(port)
  151. return nil
  152. }
  153. from, to, err := parseJSONStringPort(data)
  154. if err == nil {
  155. v.From = uint32(from)
  156. v.To = uint32(to)
  157. if v.From > v.To {
  158. return errors.New("invalid port range ", v.From, " -> ", v.To)
  159. }
  160. return nil
  161. }
  162. return errors.New("invalid port range: ", string(data))
  163. }
  164. type PortList struct {
  165. Range []PortRange
  166. }
  167. func (list *PortList) Build() *net.PortList {
  168. portList := new(net.PortList)
  169. for _, r := range list.Range {
  170. portList.Range = append(portList.Range, r.Build())
  171. }
  172. return portList
  173. }
  174. func (v PortList) MarshalJSON() ([]byte, error) {
  175. return json.Marshal(v.String())
  176. }
  177. func (v PortList) String() string {
  178. ports := []string{}
  179. for _, port := range v.Range {
  180. if port.From == port.To {
  181. p := strconv.Itoa(int(port.From))
  182. ports = append(ports, p)
  183. } else {
  184. p := fmt.Sprintf("%d-%d", port.From, port.To)
  185. ports = append(ports, p)
  186. }
  187. }
  188. return strings.Join(ports, ",")
  189. }
  190. // UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON
  191. func (list *PortList) UnmarshalJSON(data []byte) error {
  192. var listStr string
  193. var number uint32
  194. if err := json.Unmarshal(data, &listStr); err != nil {
  195. if err2 := json.Unmarshal(data, &number); err2 != nil {
  196. return errors.New("invalid port: ", string(data)).Base(err2)
  197. }
  198. }
  199. rangelist := strings.Split(listStr, ",")
  200. for _, rangeStr := range rangelist {
  201. trimmed := strings.TrimSpace(rangeStr)
  202. if len(trimmed) > 0 {
  203. if strings.Contains(trimmed, "-") || strings.Contains(trimmed, "env:") {
  204. from, to, err := parseStringPort(trimmed)
  205. if err != nil {
  206. return errors.New("invalid port range: ", trimmed).Base(err)
  207. }
  208. list.Range = append(list.Range, PortRange{From: uint32(from), To: uint32(to)})
  209. } else {
  210. port, err := parseIntPort([]byte(trimmed))
  211. if err != nil {
  212. return errors.New("invalid port: ", trimmed).Base(err)
  213. }
  214. list.Range = append(list.Range, PortRange{From: uint32(port), To: uint32(port)})
  215. }
  216. }
  217. }
  218. if number != 0 {
  219. list.Range = append(list.Range, PortRange{From: number, To: number})
  220. }
  221. return nil
  222. }
  223. type User struct {
  224. EmailString string `json:"email"`
  225. LevelByte byte `json:"level"`
  226. }
  227. func (v *User) Build() *protocol.User {
  228. return &protocol.User{
  229. Email: v.EmailString,
  230. Level: uint32(v.LevelByte),
  231. }
  232. }
  233. // Int32Range deserializes from "1-2" or 1, so can deserialize from both int and number.
  234. // Negative integers can be passed as sentinel values, but do not parse as ranges.
  235. // Value will be exchanged if From > To, use .Left and .Right to get original value if need.
  236. type Int32Range struct {
  237. Left int32
  238. Right int32
  239. From int32
  240. To int32
  241. }
  242. func (v Int32Range) MarshalJSON() ([]byte, error) {
  243. return json.Marshal(v.String())
  244. }
  245. func (v Int32Range) String() string {
  246. if v.Left == v.Right {
  247. return strconv.Itoa(int(v.Left))
  248. } else {
  249. return fmt.Sprintf("%d-%d", v.Left, v.Right)
  250. }
  251. }
  252. func (v *Int32Range) UnmarshalJSON(data []byte) error {
  253. defer v.ensureOrder()
  254. var str string
  255. var rawint int32
  256. if err := json.Unmarshal(data, &str); err == nil {
  257. left, right, err := ParseRangeString(str)
  258. if err == nil {
  259. v.Left, v.Right = int32(left), int32(right)
  260. return nil
  261. }
  262. } else if err := json.Unmarshal(data, &rawint); err == nil {
  263. v.Left = rawint
  264. v.Right = rawint
  265. return nil
  266. }
  267. return errors.New("Invalid integer range, expected either string of form \"1-2\" or plain integer.")
  268. }
  269. // ensureOrder() gives value to .From & .To and make sure .From < .To
  270. func (r *Int32Range) ensureOrder() {
  271. r.From, r.To = r.Left, r.Right
  272. if r.From > r.To {
  273. r.From, r.To = r.To, r.From
  274. }
  275. }
  276. // "-114-514" → ["-114","514"]
  277. // "-1919--810" → ["-1919","-810"]
  278. func splitFromSecondDash(s string) []string {
  279. parts := strings.SplitN(s, "-", 3)
  280. if len(parts) < 3 {
  281. return []string{s}
  282. }
  283. return []string{parts[0] + "-" + parts[1], parts[2]}
  284. }
  285. // Parse rang in string. Support negative number.
  286. // eg: "114-514" "-114-514" "-1919--810" "114514" ""(return 0)
  287. func ParseRangeString(str string) (int, int, error) {
  288. // for number in string format like "114" or "-1"
  289. if value, err := strconv.Atoi(str); err == nil {
  290. return value, value, nil
  291. }
  292. // for empty "", we treat it as 0
  293. if str == "" {
  294. return 0, 0, nil
  295. }
  296. // for range value, like "114-514"
  297. var pair []string
  298. // Process sth like "-114-514" "-1919--810"
  299. if strings.HasPrefix(str, "-") {
  300. pair = splitFromSecondDash(str)
  301. } else {
  302. pair = strings.SplitN(str, "-", 2)
  303. }
  304. if len(pair) == 2 {
  305. left, err := strconv.Atoi(pair[0])
  306. right, err2 := strconv.Atoi(pair[1])
  307. if err == nil && err2 == nil {
  308. return left, right, nil
  309. }
  310. }
  311. return 0, 0, errors.New("invalid range string: ", str)
  312. }