freedom.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package conf
  2. import (
  3. "net"
  4. "strconv"
  5. "strings"
  6. "github.com/golang/protobuf/proto"
  7. v2net "github.com/xtls/xray-core/common/net"
  8. "github.com/xtls/xray-core/common/protocol"
  9. "github.com/xtls/xray-core/proxy/freedom"
  10. )
  11. type FreedomConfig struct {
  12. DomainStrategy string `json:"domainStrategy"`
  13. Timeout *uint32 `json:"timeout"`
  14. Redirect string `json:"redirect"`
  15. UserLevel uint32 `json:"userLevel"`
  16. Fragment *Fragment `json:"fragment"`
  17. }
  18. type Fragment struct {
  19. Packets string `json:"packets"`
  20. Length string `json:"length"`
  21. Interval string `json:"interval"`
  22. }
  23. // Build implements Buildable
  24. func (c *FreedomConfig) Build() (proto.Message, error) {
  25. config := new(freedom.Config)
  26. config.DomainStrategy = freedom.Config_AS_IS
  27. switch strings.ToLower(c.DomainStrategy) {
  28. case "useip", "use_ip", "use-ip":
  29. config.DomainStrategy = freedom.Config_USE_IP
  30. case "useip4", "useipv4", "use_ip4", "use_ipv4", "use_ip_v4", "use-ip4", "use-ipv4", "use-ip-v4":
  31. config.DomainStrategy = freedom.Config_USE_IP4
  32. case "useip6", "useipv6", "use_ip6", "use_ipv6", "use_ip_v6", "use-ip6", "use-ipv6", "use-ip-v6":
  33. config.DomainStrategy = freedom.Config_USE_IP6
  34. }
  35. if c.Fragment != nil {
  36. config.Fragment = new(freedom.Fragment)
  37. var err, err2 error
  38. switch strings.ToLower(c.Fragment.Packets) {
  39. case "tlshello":
  40. // TLS Hello Fragmentation (into multiple handshake messages)
  41. config.Fragment.PacketsFrom = 0
  42. config.Fragment.PacketsTo = 1
  43. case "":
  44. // TCP Segmentation (all packets)
  45. config.Fragment.PacketsFrom = 0
  46. config.Fragment.PacketsTo = 0
  47. default:
  48. // TCP Segmentation (range)
  49. packetsFromTo := strings.Split(c.Fragment.Packets, "-")
  50. if len(packetsFromTo) == 2 {
  51. config.Fragment.PacketsFrom, err = strconv.ParseUint(packetsFromTo[0], 10, 64)
  52. config.Fragment.PacketsTo, err2 = strconv.ParseUint(packetsFromTo[1], 10, 64)
  53. } else {
  54. config.Fragment.PacketsFrom, err = strconv.ParseUint(packetsFromTo[0], 10, 64)
  55. config.Fragment.PacketsTo = config.Fragment.PacketsFrom
  56. }
  57. if err != nil {
  58. return nil, newError("Invalid PacketsFrom").Base(err)
  59. }
  60. if err2 != nil {
  61. return nil, newError("Invalid PacketsTo").Base(err2)
  62. }
  63. if config.Fragment.PacketsFrom > config.Fragment.PacketsTo {
  64. config.Fragment.PacketsFrom, config.Fragment.PacketsTo = config.Fragment.PacketsTo, config.Fragment.PacketsFrom
  65. }
  66. if config.Fragment.PacketsFrom == 0 {
  67. return nil, newError("PacketsFrom can't be 0")
  68. }
  69. }
  70. {
  71. if c.Fragment.Length == "" {
  72. return nil, newError("Length can't be empty")
  73. }
  74. lengthMinMax := strings.Split(c.Fragment.Length, "-")
  75. if len(lengthMinMax) == 2 {
  76. config.Fragment.LengthMin, err = strconv.ParseUint(lengthMinMax[0], 10, 64)
  77. config.Fragment.LengthMax, err2 = strconv.ParseUint(lengthMinMax[1], 10, 64)
  78. } else {
  79. config.Fragment.LengthMin, err = strconv.ParseUint(lengthMinMax[0], 10, 64)
  80. config.Fragment.LengthMax = config.Fragment.LengthMin
  81. }
  82. if err != nil {
  83. return nil, newError("Invalid LengthMin").Base(err)
  84. }
  85. if err2 != nil {
  86. return nil, newError("Invalid LengthMax").Base(err2)
  87. }
  88. if config.Fragment.LengthMin > config.Fragment.LengthMax {
  89. config.Fragment.LengthMin, config.Fragment.LengthMax = config.Fragment.LengthMax, config.Fragment.LengthMin
  90. }
  91. if config.Fragment.LengthMin == 0 {
  92. return nil, newError("LengthMin can't be 0")
  93. }
  94. }
  95. {
  96. if c.Fragment.Interval == "" {
  97. return nil, newError("Interval can't be empty")
  98. }
  99. intervalMinMax := strings.Split(c.Fragment.Interval, "-")
  100. if len(intervalMinMax) == 2 {
  101. config.Fragment.IntervalMin, err = strconv.ParseUint(intervalMinMax[0], 10, 64)
  102. config.Fragment.IntervalMax, err2 = strconv.ParseUint(intervalMinMax[1], 10, 64)
  103. } else {
  104. config.Fragment.IntervalMin, err = strconv.ParseUint(intervalMinMax[0], 10, 64)
  105. config.Fragment.IntervalMax = config.Fragment.IntervalMin
  106. }
  107. if err != nil {
  108. return nil, newError("Invalid IntervalMin").Base(err)
  109. }
  110. if err2 != nil {
  111. return nil, newError("Invalid IntervalMax").Base(err2)
  112. }
  113. if config.Fragment.IntervalMin > config.Fragment.IntervalMax {
  114. config.Fragment.IntervalMin, config.Fragment.IntervalMax = config.Fragment.IntervalMax, config.Fragment.IntervalMin
  115. }
  116. }
  117. }
  118. if c.Timeout != nil {
  119. config.Timeout = *c.Timeout
  120. }
  121. config.UserLevel = c.UserLevel
  122. if len(c.Redirect) > 0 {
  123. host, portStr, err := net.SplitHostPort(c.Redirect)
  124. if err != nil {
  125. return nil, newError("invalid redirect address: ", c.Redirect, ": ", err).Base(err)
  126. }
  127. port, err := v2net.PortFromString(portStr)
  128. if err != nil {
  129. return nil, newError("invalid redirect port: ", c.Redirect, ": ", err).Base(err)
  130. }
  131. config.DestinationOverride = &freedom.DestinationOverride{
  132. Server: &protocol.ServerEndpoint{
  133. Port: uint32(port),
  134. },
  135. }
  136. if len(host) > 0 {
  137. config.DestinationOverride.Server.Address = v2net.NewIPOrDomain(v2net.ParseAddress(host))
  138. }
  139. }
  140. return config, nil
  141. }