github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/infra/conf/cfgcommon/common.go (about)

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