github.com/eagleql/xray-core@v1.4.4/infra/conf/common.go (about)

     1  package conf
     2  
     3  import (
     4  	"encoding/json"
     5  	"os"
     6  	"strings"
     7  
     8  	"github.com/eagleql/xray-core/common/net"
     9  	"github.com/eagleql/xray-core/common/protocol"
    10  )
    11  
    12  type StringList []string
    13  
    14  func NewStringList(raw []string) *StringList {
    15  	list := StringList(raw)
    16  	return &list
    17  }
    18  
    19  func (v StringList) Len() int {
    20  	return len(v)
    21  }
    22  
    23  func (v *StringList) UnmarshalJSON(data []byte) error {
    24  	var strarray []string
    25  	if err := json.Unmarshal(data, &strarray); err == nil {
    26  		*v = *NewStringList(strarray)
    27  		return nil
    28  	}
    29  
    30  	var rawstr string
    31  	if err := json.Unmarshal(data, &rawstr); err == nil {
    32  		strlist := strings.Split(rawstr, ",")
    33  		*v = *NewStringList(strlist)
    34  		return nil
    35  	}
    36  	return newError("unknown format of a string list: " + string(data))
    37  }
    38  
    39  type Address struct {
    40  	net.Address
    41  }
    42  
    43  func (v *Address) UnmarshalJSON(data []byte) error {
    44  	var rawStr string
    45  	if err := json.Unmarshal(data, &rawStr); err != nil {
    46  		return newError("invalid address: ", string(data)).Base(err)
    47  	}
    48  	v.Address = net.ParseAddress(rawStr)
    49  
    50  	return nil
    51  }
    52  
    53  func (v *Address) Build() *net.IPOrDomain {
    54  	return net.NewIPOrDomain(v.Address)
    55  }
    56  
    57  type Network string
    58  
    59  func (v Network) Build() net.Network {
    60  	switch strings.ToLower(string(v)) {
    61  	case "tcp":
    62  		return net.Network_TCP
    63  	case "udp":
    64  		return net.Network_UDP
    65  	case "unix":
    66  		return net.Network_UNIX
    67  	default:
    68  		return net.Network_Unknown
    69  	}
    70  }
    71  
    72  type NetworkList []Network
    73  
    74  func (v *NetworkList) UnmarshalJSON(data []byte) error {
    75  	var strarray []Network
    76  	if err := json.Unmarshal(data, &strarray); err == nil {
    77  		nl := NetworkList(strarray)
    78  		*v = nl
    79  		return nil
    80  	}
    81  
    82  	var rawstr Network
    83  	if err := json.Unmarshal(data, &rawstr); err == nil {
    84  		strlist := strings.Split(string(rawstr), ",")
    85  		nl := make([]Network, len(strlist))
    86  		for idx, network := range strlist {
    87  			nl[idx] = Network(network)
    88  		}
    89  		*v = nl
    90  		return nil
    91  	}
    92  	return newError("unknown format of a string list: " + string(data))
    93  }
    94  
    95  func (v *NetworkList) Build() []net.Network {
    96  	if v == nil {
    97  		return []net.Network{net.Network_TCP}
    98  	}
    99  
   100  	list := make([]net.Network, 0, len(*v))
   101  	for _, network := range *v {
   102  		list = append(list, network.Build())
   103  	}
   104  	return list
   105  }
   106  
   107  func parseIntPort(data []byte) (net.Port, error) {
   108  	var intPort uint32
   109  	err := json.Unmarshal(data, &intPort)
   110  	if err != nil {
   111  		return net.Port(0), err
   112  	}
   113  	return net.PortFromInt(intPort)
   114  }
   115  
   116  func parseStringPort(s string) (net.Port, net.Port, error) {
   117  	if strings.HasPrefix(s, "env:") {
   118  		s = s[4:]
   119  		s = os.Getenv(s)
   120  	}
   121  
   122  	pair := strings.SplitN(s, "-", 2)
   123  	if len(pair) == 0 {
   124  		return net.Port(0), net.Port(0), newError("invalid port range: ", s)
   125  	}
   126  	if len(pair) == 1 {
   127  		port, err := net.PortFromString(pair[0])
   128  		return port, port, err
   129  	}
   130  
   131  	fromPort, err := net.PortFromString(pair[0])
   132  	if err != nil {
   133  		return net.Port(0), net.Port(0), err
   134  	}
   135  	toPort, err := net.PortFromString(pair[1])
   136  	if err != nil {
   137  		return net.Port(0), net.Port(0), err
   138  	}
   139  	return fromPort, toPort, nil
   140  }
   141  
   142  func parseJSONStringPort(data []byte) (net.Port, net.Port, error) {
   143  	var s string
   144  	err := json.Unmarshal(data, &s)
   145  	if err != nil {
   146  		return net.Port(0), net.Port(0), err
   147  	}
   148  	return parseStringPort(s)
   149  }
   150  
   151  type PortRange struct {
   152  	From uint32
   153  	To   uint32
   154  }
   155  
   156  func (v *PortRange) Build() *net.PortRange {
   157  	return &net.PortRange{
   158  		From: v.From,
   159  		To:   v.To,
   160  	}
   161  }
   162  
   163  // UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON
   164  func (v *PortRange) UnmarshalJSON(data []byte) error {
   165  	port, err := parseIntPort(data)
   166  	if err == nil {
   167  		v.From = uint32(port)
   168  		v.To = uint32(port)
   169  		return nil
   170  	}
   171  
   172  	from, to, err := parseJSONStringPort(data)
   173  	if err == nil {
   174  		v.From = uint32(from)
   175  		v.To = uint32(to)
   176  		if v.From > v.To {
   177  			return newError("invalid port range ", v.From, " -> ", v.To)
   178  		}
   179  		return nil
   180  	}
   181  
   182  	return newError("invalid port range: ", string(data))
   183  }
   184  
   185  type PortList struct {
   186  	Range []PortRange
   187  }
   188  
   189  func (list *PortList) Build() *net.PortList {
   190  	portList := new(net.PortList)
   191  	for _, r := range list.Range {
   192  		portList.Range = append(portList.Range, r.Build())
   193  	}
   194  	return portList
   195  }
   196  
   197  // UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON
   198  func (list *PortList) UnmarshalJSON(data []byte) error {
   199  	var listStr string
   200  	var number uint32
   201  	if err := json.Unmarshal(data, &listStr); err != nil {
   202  		if err2 := json.Unmarshal(data, &number); err2 != nil {
   203  			return newError("invalid port: ", string(data)).Base(err2)
   204  		}
   205  	}
   206  	rangelist := strings.Split(listStr, ",")
   207  	for _, rangeStr := range rangelist {
   208  		trimmed := strings.TrimSpace(rangeStr)
   209  		if len(trimmed) > 0 {
   210  			if strings.Contains(trimmed, "-") {
   211  				from, to, err := parseStringPort(trimmed)
   212  				if err != nil {
   213  					return newError("invalid port range: ", trimmed).Base(err)
   214  				}
   215  				list.Range = append(list.Range, PortRange{From: uint32(from), To: uint32(to)})
   216  			} else {
   217  				port, err := parseIntPort([]byte(trimmed))
   218  				if err != nil {
   219  					return newError("invalid port: ", trimmed).Base(err)
   220  				}
   221  				list.Range = append(list.Range, PortRange{From: uint32(port), To: uint32(port)})
   222  			}
   223  		}
   224  	}
   225  	if number != 0 {
   226  		list.Range = append(list.Range, PortRange{From: number, To: number})
   227  	}
   228  	return nil
   229  }
   230  
   231  type User struct {
   232  	EmailString string `json:"email"`
   233  	LevelByte   byte   `json:"level"`
   234  }
   235  
   236  func (v *User) Build() *protocol.User {
   237  	return &protocol.User{
   238  		Email: v.EmailString,
   239  		Level: uint32(v.LevelByte),
   240  	}
   241  }