github.com/metacubex/mihomo@v1.18.5/adapter/parser.go (about)

     1  package adapter
     2  
     3  import (
     4  	"fmt"
     5  
     6  	tlsC "github.com/metacubex/mihomo/component/tls"
     7  
     8  	"github.com/metacubex/mihomo/adapter/outbound"
     9  	"github.com/metacubex/mihomo/common/structure"
    10  	C "github.com/metacubex/mihomo/constant"
    11  )
    12  
    13  func ParseProxy(mapping map[string]any) (C.Proxy, error) {
    14  	decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true, KeyReplacer: structure.DefaultKeyReplacer})
    15  	proxyType, existType := mapping["type"].(string)
    16  	if !existType {
    17  		return nil, fmt.Errorf("missing type")
    18  	}
    19  
    20  	var (
    21  		proxy C.ProxyAdapter
    22  		err   error
    23  	)
    24  	switch proxyType {
    25  	case "ss":
    26  		ssOption := &outbound.ShadowSocksOption{ClientFingerprint: tlsC.GetGlobalFingerprint()}
    27  		err = decoder.Decode(mapping, ssOption)
    28  		if err != nil {
    29  			break
    30  		}
    31  		proxy, err = outbound.NewShadowSocks(*ssOption)
    32  	case "ssr":
    33  		ssrOption := &outbound.ShadowSocksROption{}
    34  		err = decoder.Decode(mapping, ssrOption)
    35  		if err != nil {
    36  			break
    37  		}
    38  		proxy, err = outbound.NewShadowSocksR(*ssrOption)
    39  	case "socks5":
    40  		socksOption := &outbound.Socks5Option{}
    41  		err = decoder.Decode(mapping, socksOption)
    42  		if err != nil {
    43  			break
    44  		}
    45  		proxy, err = outbound.NewSocks5(*socksOption)
    46  	case "http":
    47  		httpOption := &outbound.HttpOption{}
    48  		err = decoder.Decode(mapping, httpOption)
    49  		if err != nil {
    50  			break
    51  		}
    52  		proxy, err = outbound.NewHttp(*httpOption)
    53  	case "vmess":
    54  		vmessOption := &outbound.VmessOption{
    55  			HTTPOpts: outbound.HTTPOptions{
    56  				Method: "GET",
    57  				Path:   []string{"/"},
    58  			},
    59  			ClientFingerprint: tlsC.GetGlobalFingerprint(),
    60  		}
    61  
    62  		err = decoder.Decode(mapping, vmessOption)
    63  		if err != nil {
    64  			break
    65  		}
    66  		proxy, err = outbound.NewVmess(*vmessOption)
    67  	case "vless":
    68  		vlessOption := &outbound.VlessOption{ClientFingerprint: tlsC.GetGlobalFingerprint()}
    69  		err = decoder.Decode(mapping, vlessOption)
    70  		if err != nil {
    71  			break
    72  		}
    73  		proxy, err = outbound.NewVless(*vlessOption)
    74  	case "snell":
    75  		snellOption := &outbound.SnellOption{}
    76  		err = decoder.Decode(mapping, snellOption)
    77  		if err != nil {
    78  			break
    79  		}
    80  		proxy, err = outbound.NewSnell(*snellOption)
    81  	case "trojan":
    82  		trojanOption := &outbound.TrojanOption{ClientFingerprint: tlsC.GetGlobalFingerprint()}
    83  		err = decoder.Decode(mapping, trojanOption)
    84  		if err != nil {
    85  			break
    86  		}
    87  		proxy, err = outbound.NewTrojan(*trojanOption)
    88  	case "hysteria":
    89  		hyOption := &outbound.HysteriaOption{}
    90  		err = decoder.Decode(mapping, hyOption)
    91  		if err != nil {
    92  			break
    93  		}
    94  		proxy, err = outbound.NewHysteria(*hyOption)
    95  	case "hysteria2":
    96  		hyOption := &outbound.Hysteria2Option{}
    97  		err = decoder.Decode(mapping, hyOption)
    98  		if err != nil {
    99  			break
   100  		}
   101  		proxy, err = outbound.NewHysteria2(*hyOption)
   102  	case "wireguard":
   103  		wgOption := &outbound.WireGuardOption{}
   104  		err = decoder.Decode(mapping, wgOption)
   105  		if err != nil {
   106  			break
   107  		}
   108  		proxy, err = outbound.NewWireGuard(*wgOption)
   109  	case "tuic":
   110  		tuicOption := &outbound.TuicOption{}
   111  		err = decoder.Decode(mapping, tuicOption)
   112  		if err != nil {
   113  			break
   114  		}
   115  		proxy, err = outbound.NewTuic(*tuicOption)
   116  	case "direct":
   117  		directOption := &outbound.DirectOption{}
   118  		err = decoder.Decode(mapping, directOption)
   119  		if err != nil {
   120  			break
   121  		}
   122  		proxy = outbound.NewDirectWithOption(*directOption)
   123  	case "dns":
   124  		dnsOptions := &outbound.DnsOption{}
   125  		err = decoder.Decode(mapping, dnsOptions)
   126  		if err != nil {
   127  			break
   128  		}
   129  		proxy = outbound.NewDnsWithOption(*dnsOptions)
   130  	case "reject":
   131  		rejectOption := &outbound.RejectOption{}
   132  		err = decoder.Decode(mapping, rejectOption)
   133  		if err != nil {
   134  			break
   135  		}
   136  		proxy = outbound.NewRejectWithOption(*rejectOption)
   137  	case "ssh":
   138  		sshOption := &outbound.SshOption{}
   139  		err = decoder.Decode(mapping, sshOption)
   140  		if err != nil {
   141  			break
   142  		}
   143  		proxy, err = outbound.NewSsh(*sshOption)
   144  	default:
   145  		return nil, fmt.Errorf("unsupport proxy type: %s", proxyType)
   146  	}
   147  
   148  	if err != nil {
   149  		return nil, err
   150  	}
   151  
   152  	if muxMapping, muxExist := mapping["smux"].(map[string]any); muxExist {
   153  		muxOption := &outbound.SingMuxOption{}
   154  		err = decoder.Decode(muxMapping, muxOption)
   155  		if err != nil {
   156  			return nil, err
   157  		}
   158  		if muxOption.Enabled {
   159  			proxy, err = outbound.NewSingMux(*muxOption, proxy, proxy.(outbound.ProxyBase))
   160  			if err != nil {
   161  				return nil, err
   162  			}
   163  		}
   164  	}
   165  
   166  	return NewProxy(proxy), nil
   167  }