freedom.go 7.8 KB

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