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  }