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