freedom.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. package conf
  2. import (
  3. "encoding/base64"
  4. "net"
  5. "strconv"
  6. "strings"
  7. "github.com/xtls/xray-core/common/errors"
  8. v2net "github.com/xtls/xray-core/common/net"
  9. "github.com/xtls/xray-core/common/protocol"
  10. "github.com/xtls/xray-core/proxy/freedom"
  11. "google.golang.org/protobuf/proto"
  12. )
  13. type FreedomConfig struct {
  14. DomainStrategy string `json:"domainStrategy"`
  15. Timeout *uint32 `json:"timeout"`
  16. Redirect string `json:"redirect"`
  17. UserLevel uint32 `json:"userLevel"`
  18. Fragment *Fragment `json:"fragment"`
  19. Noise *Noise `json:"noise"`
  20. Noises []*Noise `json:"noises"`
  21. ProxyProtocol uint32 `json:"proxyProtocol"`
  22. }
  23. type Fragment struct {
  24. Packets string `json:"packets"`
  25. Length string `json:"length"`
  26. Interval string `json:"interval"`
  27. }
  28. type Noise struct {
  29. Type string `json:"type"`
  30. Packet string `json:"packet"`
  31. Delay *Int32Range `json:"delay"`
  32. }
  33. // Build implements Buildable
  34. func (c *FreedomConfig) Build() (proto.Message, error) {
  35. config := new(freedom.Config)
  36. switch strings.ToLower(c.DomainStrategy) {
  37. case "asis", "":
  38. config.DomainStrategy = freedom.Config_AS_IS
  39. case "useip":
  40. config.DomainStrategy = freedom.Config_USE_IP
  41. case "useipv4":
  42. config.DomainStrategy = freedom.Config_USE_IP4
  43. case "useipv6":
  44. config.DomainStrategy = freedom.Config_USE_IP6
  45. case "useipv4v6":
  46. config.DomainStrategy = freedom.Config_USE_IP46
  47. case "useipv6v4":
  48. config.DomainStrategy = freedom.Config_USE_IP64
  49. case "forceip":
  50. config.DomainStrategy = freedom.Config_FORCE_IP
  51. case "forceipv4":
  52. config.DomainStrategy = freedom.Config_FORCE_IP4
  53. case "forceipv6":
  54. config.DomainStrategy = freedom.Config_FORCE_IP6
  55. case "forceipv4v6":
  56. config.DomainStrategy = freedom.Config_FORCE_IP46
  57. case "forceipv6v4":
  58. config.DomainStrategy = freedom.Config_FORCE_IP64
  59. default:
  60. return nil, errors.New("unsupported domain strategy: ", c.DomainStrategy)
  61. }
  62. if c.Fragment != nil {
  63. config.Fragment = new(freedom.Fragment)
  64. var err, err2 error
  65. switch strings.ToLower(c.Fragment.Packets) {
  66. case "tlshello":
  67. // TLS Hello Fragmentation (into multiple handshake messages)
  68. config.Fragment.PacketsFrom = 0
  69. config.Fragment.PacketsTo = 1
  70. case "":
  71. // TCP Segmentation (all packets)
  72. config.Fragment.PacketsFrom = 0
  73. config.Fragment.PacketsTo = 0
  74. default:
  75. // TCP Segmentation (range)
  76. packetsFromTo := strings.Split(c.Fragment.Packets, "-")
  77. if len(packetsFromTo) == 2 {
  78. config.Fragment.PacketsFrom, err = strconv.ParseUint(packetsFromTo[0], 10, 64)
  79. config.Fragment.PacketsTo, err2 = strconv.ParseUint(packetsFromTo[1], 10, 64)
  80. } else {
  81. config.Fragment.PacketsFrom, err = strconv.ParseUint(packetsFromTo[0], 10, 64)
  82. config.Fragment.PacketsTo = config.Fragment.PacketsFrom
  83. }
  84. if err != nil {
  85. return nil, errors.New("Invalid PacketsFrom").Base(err)
  86. }
  87. if err2 != nil {
  88. return nil, errors.New("Invalid PacketsTo").Base(err2)
  89. }
  90. if config.Fragment.PacketsFrom > config.Fragment.PacketsTo {
  91. config.Fragment.PacketsFrom, config.Fragment.PacketsTo = config.Fragment.PacketsTo, config.Fragment.PacketsFrom
  92. }
  93. if config.Fragment.PacketsFrom == 0 {
  94. return nil, errors.New("PacketsFrom can't be 0")
  95. }
  96. }
  97. {
  98. if c.Fragment.Length == "" {
  99. return nil, errors.New("Length can't be empty")
  100. }
  101. lengthMinMax := strings.Split(c.Fragment.Length, "-")
  102. if len(lengthMinMax) == 2 {
  103. config.Fragment.LengthMin, err = strconv.ParseUint(lengthMinMax[0], 10, 64)
  104. config.Fragment.LengthMax, err2 = strconv.ParseUint(lengthMinMax[1], 10, 64)
  105. } else {
  106. config.Fragment.LengthMin, err = strconv.ParseUint(lengthMinMax[0], 10, 64)
  107. config.Fragment.LengthMax = config.Fragment.LengthMin
  108. }
  109. if err != nil {
  110. return nil, errors.New("Invalid LengthMin").Base(err)
  111. }
  112. if err2 != nil {
  113. return nil, errors.New("Invalid LengthMax").Base(err2)
  114. }
  115. if config.Fragment.LengthMin > config.Fragment.LengthMax {
  116. config.Fragment.LengthMin, config.Fragment.LengthMax = config.Fragment.LengthMax, config.Fragment.LengthMin
  117. }
  118. if config.Fragment.LengthMin == 0 {
  119. return nil, errors.New("LengthMin can't be 0")
  120. }
  121. }
  122. {
  123. if c.Fragment.Interval == "" {
  124. return nil, errors.New("Interval can't be empty")
  125. }
  126. intervalMinMax := strings.Split(c.Fragment.Interval, "-")
  127. if len(intervalMinMax) == 2 {
  128. config.Fragment.IntervalMin, err = strconv.ParseUint(intervalMinMax[0], 10, 64)
  129. config.Fragment.IntervalMax, err2 = strconv.ParseUint(intervalMinMax[1], 10, 64)
  130. } else {
  131. config.Fragment.IntervalMin, err = strconv.ParseUint(intervalMinMax[0], 10, 64)
  132. config.Fragment.IntervalMax = config.Fragment.IntervalMin
  133. }
  134. if err != nil {
  135. return nil, errors.New("Invalid IntervalMin").Base(err)
  136. }
  137. if err2 != nil {
  138. return nil, errors.New("Invalid IntervalMax").Base(err2)
  139. }
  140. if config.Fragment.IntervalMin > config.Fragment.IntervalMax {
  141. config.Fragment.IntervalMin, config.Fragment.IntervalMax = config.Fragment.IntervalMax, config.Fragment.IntervalMin
  142. }
  143. }
  144. }
  145. if c.Noise != nil {
  146. return nil, errors.PrintRemovedFeatureError("noise = { ... }", "noises = [ { ... } ]")
  147. }
  148. if c.Noises != nil {
  149. for _, n := range c.Noises {
  150. NConfig, err := ParseNoise(n)
  151. if err != nil {
  152. return nil, err
  153. }
  154. config.Noises = append(config.Noises, NConfig)
  155. }
  156. }
  157. if c.Timeout != nil {
  158. config.Timeout = *c.Timeout
  159. }
  160. config.UserLevel = c.UserLevel
  161. if len(c.Redirect) > 0 {
  162. host, portStr, err := net.SplitHostPort(c.Redirect)
  163. if err != nil {
  164. return nil, errors.New("invalid redirect address: ", c.Redirect, ": ", err).Base(err)
  165. }
  166. port, err := v2net.PortFromString(portStr)
  167. if err != nil {
  168. return nil, errors.New("invalid redirect port: ", c.Redirect, ": ", err).Base(err)
  169. }
  170. config.DestinationOverride = &freedom.DestinationOverride{
  171. Server: &protocol.ServerEndpoint{
  172. Port: uint32(port),
  173. },
  174. }
  175. if len(host) > 0 {
  176. config.DestinationOverride.Server.Address = v2net.NewIPOrDomain(v2net.ParseAddress(host))
  177. }
  178. }
  179. if c.ProxyProtocol > 0 && c.ProxyProtocol <= 2 {
  180. config.ProxyProtocol = c.ProxyProtocol
  181. }
  182. return config, nil
  183. }
  184. func ParseNoise(noise *Noise) (*freedom.Noise, error) {
  185. var err, err2 error
  186. NConfig := new(freedom.Noise)
  187. switch strings.ToLower(noise.Type) {
  188. case "rand":
  189. randValue := strings.Split(noise.Packet, "-")
  190. if len(randValue) > 2 {
  191. return nil, errors.New("Only 2 values are allowed for rand")
  192. }
  193. if len(randValue) == 2 {
  194. NConfig.LengthMin, err = strconv.ParseUint(randValue[0], 10, 64)
  195. NConfig.LengthMax, err2 = strconv.ParseUint(randValue[1], 10, 64)
  196. }
  197. if len(randValue) == 1 {
  198. NConfig.LengthMin, err = strconv.ParseUint(randValue[0], 10, 64)
  199. NConfig.LengthMax = NConfig.LengthMin
  200. }
  201. if err != nil {
  202. return nil, errors.New("invalid value for rand LengthMin").Base(err)
  203. }
  204. if err2 != nil {
  205. return nil, errors.New("invalid value for rand LengthMax").Base(err2)
  206. }
  207. if NConfig.LengthMin > NConfig.LengthMax {
  208. NConfig.LengthMin, NConfig.LengthMax = NConfig.LengthMax, NConfig.LengthMin
  209. }
  210. if NConfig.LengthMin == 0 {
  211. return nil, errors.New("rand lengthMin or lengthMax cannot be 0")
  212. }
  213. case "str":
  214. //user input string
  215. NConfig.StrNoise = []byte(strings.TrimSpace(noise.Packet))
  216. case "base64":
  217. //user input base64
  218. NConfig.StrNoise, err = base64.StdEncoding.DecodeString(strings.TrimSpace(noise.Packet))
  219. if err != nil {
  220. return nil, errors.New("Invalid base64 string")
  221. }
  222. default:
  223. return nil, errors.New("Invalid packet,only rand,str,base64 are supported")
  224. }
  225. if noise.Delay != nil {
  226. if noise.Delay.From != 0 && noise.Delay.To != 0 {
  227. NConfig.DelayMin = uint64(noise.Delay.From)
  228. NConfig.DelayMax = uint64(noise.Delay.To)
  229. if NConfig.DelayMin > NConfig.LengthMax {
  230. NConfig.DelayMin, NConfig.DelayMax = NConfig.LengthMax, NConfig.DelayMin
  231. }
  232. } else {
  233. return nil, errors.New("DelayMin or DelayMax cannot be zero")
  234. }
  235. } else {
  236. NConfig.DelayMin = 0
  237. NConfig.DelayMax = 0
  238. }
  239. return NConfig, nil
  240. }