github.com/yaling888/clash@v1.53.0/adapter/parser.go (about)

     1  package adapter
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/yaling888/clash/adapter/outbound"
     8  	"github.com/yaling888/clash/common/structure"
     9  	"github.com/yaling888/clash/common/util"
    10  	C "github.com/yaling888/clash/constant"
    11  )
    12  
    13  type ProxyOption struct {
    14  	ForceCertVerify bool
    15  	ForceUDP        bool
    16  	DisableUDP      bool
    17  	DisableDNS      bool
    18  	AutoCipher      bool
    19  	RandomHost      bool
    20  	PrefixName      string
    21  }
    22  
    23  func ParseProxy(mapping map[string]any, option ProxyOption) (C.Proxy, error) {
    24  	decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true})
    25  	proxyType, existType := mapping["type"].(string)
    26  	if !existType {
    27  		return nil, fmt.Errorf("missing type")
    28  	}
    29  
    30  	var (
    31  		proxy C.ProxyAdapter
    32  		err   error
    33  	)
    34  	switch proxyType {
    35  	case "ss":
    36  		ssOption := &outbound.ShadowSocksOption{RemoteDnsResolve: true}
    37  		err = decoder.Decode(mapping, ssOption)
    38  		if err != nil {
    39  			break
    40  		}
    41  		if option.ForceUDP {
    42  			ssOption.UDP = true
    43  		}
    44  		if option.DisableUDP {
    45  			ssOption.UDP = false
    46  		}
    47  		if option.RandomHost {
    48  			ssOption.RandomHost = true
    49  		}
    50  		if option.DisableDNS {
    51  			ssOption.RemoteDnsResolve = false
    52  		}
    53  		proxy, err = outbound.NewShadowSocks(*ssOption)
    54  	case "ssr":
    55  		ssrOption := &outbound.ShadowSocksROption{RemoteDnsResolve: true}
    56  		err = decoder.Decode(mapping, ssrOption)
    57  		if err != nil {
    58  			break
    59  		}
    60  		if option.ForceUDP {
    61  			ssrOption.UDP = true
    62  		}
    63  		if option.DisableUDP {
    64  			ssrOption.UDP = false
    65  		}
    66  		if option.RandomHost {
    67  			ssrOption.RandomHost = true
    68  		}
    69  		if option.DisableDNS {
    70  			ssrOption.RemoteDnsResolve = false
    71  		}
    72  		proxy, err = outbound.NewShadowSocksR(*ssrOption)
    73  	case "socks5":
    74  		socksOption := &outbound.Socks5Option{RemoteDnsResolve: true}
    75  		err = decoder.Decode(mapping, socksOption)
    76  		if err != nil {
    77  			break
    78  		}
    79  		if option.ForceCertVerify {
    80  			socksOption.SkipCertVerify = false
    81  		}
    82  		if option.ForceUDP {
    83  			socksOption.UDP = true
    84  		}
    85  		if option.DisableDNS {
    86  			socksOption.RemoteDnsResolve = false
    87  		}
    88  		proxy = outbound.NewSocks5(*socksOption)
    89  	case "http":
    90  		httpOption := &outbound.HttpOption{RemoteDnsResolve: true}
    91  		err = decoder.Decode(mapping, httpOption)
    92  		if err != nil {
    93  			break
    94  		}
    95  		if option.ForceCertVerify {
    96  			httpOption.SkipCertVerify = false
    97  		}
    98  		if option.DisableDNS {
    99  			httpOption.RemoteDnsResolve = false
   100  		}
   101  		proxy = outbound.NewHttp(*httpOption)
   102  	case "vmess":
   103  		vmessOption := &outbound.VmessOption{
   104  			HTTPOpts: outbound.HTTPOptions{
   105  				Method:  "GET",
   106  				Path:    []string{"/"},
   107  				Headers: make(map[string][]string),
   108  			},
   109  			RemoteDnsResolve: true,
   110  		}
   111  		err = decoder.Decode(mapping, vmessOption)
   112  		if err != nil {
   113  			break
   114  		}
   115  		vmessOption.HTTPOpts.Method = util.EmptyOr(strings.ToUpper(vmessOption.HTTPOpts.Method), "GET")
   116  		if option.ForceCertVerify {
   117  			vmessOption.SkipCertVerify = false
   118  		}
   119  		if option.ForceUDP {
   120  			vmessOption.UDP = true
   121  		}
   122  		if option.DisableUDP {
   123  			vmessOption.UDP = false
   124  		}
   125  		if option.AutoCipher {
   126  			vmessOption.Cipher = "auto"
   127  		}
   128  		if option.RandomHost {
   129  			vmessOption.RandomHost = true
   130  		}
   131  		if option.DisableDNS {
   132  			vmessOption.RemoteDnsResolve = false
   133  		}
   134  		proxy, err = outbound.NewVmess(*vmessOption)
   135  	case "vless":
   136  		vlessOption := &outbound.VlessOption{
   137  			HTTPOpts: outbound.HTTPOptions{
   138  				Method:  "GET",
   139  				Path:    []string{"/"},
   140  				Headers: make(map[string][]string),
   141  			},
   142  			RemoteDnsResolve: true,
   143  		}
   144  		err = decoder.Decode(mapping, vlessOption)
   145  		if err != nil {
   146  			break
   147  		}
   148  		vlessOption.HTTPOpts.Method = util.EmptyOr(strings.ToUpper(vlessOption.HTTPOpts.Method), "GET")
   149  		if option.ForceCertVerify {
   150  			vlessOption.SkipCertVerify = false
   151  		}
   152  		if option.ForceUDP {
   153  			vlessOption.UDP = true
   154  		}
   155  		if option.DisableUDP {
   156  			vlessOption.UDP = false
   157  		}
   158  		if option.DisableDNS {
   159  			vlessOption.RemoteDnsResolve = false
   160  		}
   161  		if option.RandomHost {
   162  			vlessOption.RandomHost = true
   163  		}
   164  		proxy, err = outbound.NewVless(*vlessOption)
   165  	case "snell":
   166  		snellOption := &outbound.SnellOption{RemoteDnsResolve: true}
   167  		err = decoder.Decode(mapping, snellOption)
   168  		if err != nil {
   169  			break
   170  		}
   171  		if option.ForceUDP {
   172  			snellOption.UDP = true
   173  		}
   174  		if option.DisableUDP {
   175  			snellOption.UDP = false
   176  		}
   177  		if option.RandomHost {
   178  			snellOption.RandomHost = true
   179  		}
   180  		if option.DisableDNS {
   181  			snellOption.RemoteDnsResolve = false
   182  		}
   183  		proxy, err = outbound.NewSnell(*snellOption)
   184  	case "trojan":
   185  		trojanOption := &outbound.TrojanOption{RemoteDnsResolve: true}
   186  		err = decoder.Decode(mapping, trojanOption)
   187  		if err != nil {
   188  			break
   189  		}
   190  		if option.ForceCertVerify {
   191  			trojanOption.SkipCertVerify = false
   192  		}
   193  		if option.ForceUDP {
   194  			trojanOption.UDP = true
   195  		}
   196  		if option.DisableUDP {
   197  			trojanOption.UDP = false
   198  		}
   199  		if option.DisableDNS {
   200  			trojanOption.RemoteDnsResolve = false
   201  		}
   202  		proxy, err = outbound.NewTrojan(*trojanOption)
   203  	case "wireguard":
   204  		wireguardOption := &outbound.WireGuardOption{
   205  			RemoteDnsResolve: true,
   206  		}
   207  		err = decoder.Decode(mapping, wireguardOption)
   208  		if err != nil {
   209  			break
   210  		}
   211  		if option.ForceUDP {
   212  			wireguardOption.UDP = true
   213  		}
   214  		proxy, err = outbound.NewWireGuard(*wireguardOption)
   215  	default:
   216  		return nil, fmt.Errorf("unsupport proxy type: %s", proxyType)
   217  	}
   218  
   219  	if err != nil {
   220  		return nil, err
   221  	}
   222  
   223  	return NewProxy(proxy), nil
   224  }