2021-06-10 14:05:56 +08:00
|
|
|
package adapter
|
2019-12-08 12:17:24 +08:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2023-02-07 01:26:08 +08:00
|
|
|
|
2023-11-03 21:01:45 +08:00
|
|
|
tlsC "github.com/metacubex/mihomo/component/tls"
|
2023-02-07 16:08:59 +08:00
|
|
|
|
2023-11-03 21:01:45 +08:00
|
|
|
"github.com/metacubex/mihomo/adapter/outbound"
|
|
|
|
"github.com/metacubex/mihomo/common/structure"
|
|
|
|
C "github.com/metacubex/mihomo/constant"
|
2019-12-08 12:17:24 +08:00
|
|
|
)
|
|
|
|
|
2022-11-27 13:44:38 +08:00
|
|
|
func ParseProxy(mapping map[string]any) (C.Proxy, error) {
|
2022-12-04 21:53:13 +08:00
|
|
|
decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true, KeyReplacer: structure.DefaultKeyReplacer})
|
2019-12-08 12:17:24 +08:00
|
|
|
proxyType, existType := mapping["type"].(string)
|
|
|
|
if !existType {
|
2020-08-25 22:19:59 +08:00
|
|
|
return nil, fmt.Errorf("missing type")
|
2019-12-08 12:17:24 +08:00
|
|
|
}
|
|
|
|
|
2020-08-25 22:19:59 +08:00
|
|
|
var (
|
|
|
|
proxy C.ProxyAdapter
|
|
|
|
err error
|
|
|
|
)
|
2019-12-08 12:17:24 +08:00
|
|
|
switch proxyType {
|
|
|
|
case "ss":
|
2023-03-14 17:45:37 +08:00
|
|
|
ssOption := &outbound.ShadowSocksOption{ClientFingerprint: tlsC.GetGlobalFingerprint()}
|
2019-12-08 12:17:24 +08:00
|
|
|
err = decoder.Decode(mapping, ssOption)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
2021-06-10 14:05:56 +08:00
|
|
|
proxy, err = outbound.NewShadowSocks(*ssOption)
|
2020-07-22 23:02:15 +08:00
|
|
|
case "ssr":
|
2021-06-10 14:05:56 +08:00
|
|
|
ssrOption := &outbound.ShadowSocksROption{}
|
2020-07-22 23:02:15 +08:00
|
|
|
err = decoder.Decode(mapping, ssrOption)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
2021-06-10 14:05:56 +08:00
|
|
|
proxy, err = outbound.NewShadowSocksR(*ssrOption)
|
2019-12-08 12:17:24 +08:00
|
|
|
case "socks5":
|
2021-06-10 14:05:56 +08:00
|
|
|
socksOption := &outbound.Socks5Option{}
|
2019-12-08 12:17:24 +08:00
|
|
|
err = decoder.Decode(mapping, socksOption)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
2022-07-11 13:42:28 +08:00
|
|
|
proxy, err = outbound.NewSocks5(*socksOption)
|
2019-12-08 12:17:24 +08:00
|
|
|
case "http":
|
2021-06-10 14:05:56 +08:00
|
|
|
httpOption := &outbound.HttpOption{}
|
2019-12-08 12:17:24 +08:00
|
|
|
err = decoder.Decode(mapping, httpOption)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
2022-07-11 13:42:28 +08:00
|
|
|
proxy, err = outbound.NewHttp(*httpOption)
|
2019-12-08 12:17:24 +08:00
|
|
|
case "vmess":
|
2021-06-10 14:05:56 +08:00
|
|
|
vmessOption := &outbound.VmessOption{
|
|
|
|
HTTPOpts: outbound.HTTPOptions{
|
2020-03-31 16:07:21 +08:00
|
|
|
Method: "GET",
|
|
|
|
Path: []string{"/"},
|
|
|
|
},
|
2023-03-14 17:45:37 +08:00
|
|
|
ClientFingerprint: tlsC.GetGlobalFingerprint(),
|
2023-02-07 01:26:08 +08:00
|
|
|
}
|
|
|
|
|
2019-12-08 12:17:24 +08:00
|
|
|
err = decoder.Decode(mapping, vmessOption)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
2021-06-10 14:05:56 +08:00
|
|
|
proxy, err = outbound.NewVmess(*vmessOption)
|
2021-11-17 16:03:47 +08:00
|
|
|
case "vless":
|
2023-03-14 17:45:37 +08:00
|
|
|
vlessOption := &outbound.VlessOption{ClientFingerprint: tlsC.GetGlobalFingerprint()}
|
2021-11-17 16:03:47 +08:00
|
|
|
err = decoder.Decode(mapping, vlessOption)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
proxy, err = outbound.NewVless(*vlessOption)
|
2019-12-08 12:17:24 +08:00
|
|
|
case "snell":
|
2021-06-10 14:05:56 +08:00
|
|
|
snellOption := &outbound.SnellOption{}
|
2019-12-08 12:17:24 +08:00
|
|
|
err = decoder.Decode(mapping, snellOption)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
2021-06-10 14:05:56 +08:00
|
|
|
proxy, err = outbound.NewSnell(*snellOption)
|
2020-03-19 20:26:53 +08:00
|
|
|
case "trojan":
|
2023-03-14 17:45:37 +08:00
|
|
|
trojanOption := &outbound.TrojanOption{ClientFingerprint: tlsC.GetGlobalFingerprint()}
|
2020-03-19 20:26:53 +08:00
|
|
|
err = decoder.Decode(mapping, trojanOption)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
2021-06-10 14:05:56 +08:00
|
|
|
proxy, err = outbound.NewTrojan(*trojanOption)
|
2022-06-07 13:38:45 +08:00
|
|
|
case "hysteria":
|
|
|
|
hyOption := &outbound.HysteriaOption{}
|
|
|
|
err = decoder.Decode(mapping, hyOption)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
proxy, err = outbound.NewHysteria(*hyOption)
|
2023-09-21 10:28:28 +08:00
|
|
|
case "hysteria2":
|
|
|
|
hyOption := &outbound.Hysteria2Option{}
|
|
|
|
err = decoder.Decode(mapping, hyOption)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
proxy, err = outbound.NewHysteria2(*hyOption)
|
2022-11-09 18:44:06 +08:00
|
|
|
case "wireguard":
|
2022-11-25 08:08:14 +08:00
|
|
|
wgOption := &outbound.WireGuardOption{}
|
|
|
|
err = decoder.Decode(mapping, wgOption)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
proxy, err = outbound.NewWireGuard(*wgOption)
|
|
|
|
case "tuic":
|
|
|
|
tuicOption := &outbound.TuicOption{}
|
|
|
|
err = decoder.Decode(mapping, tuicOption)
|
2022-11-09 18:44:06 +08:00
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
2022-11-25 08:08:14 +08:00
|
|
|
proxy, err = outbound.NewTuic(*tuicOption)
|
2023-08-24 23:33:03 +08:00
|
|
|
case "direct":
|
|
|
|
directOption := &outbound.DirectOption{}
|
|
|
|
err = decoder.Decode(mapping, directOption)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
proxy = outbound.NewDirectWithOption(*directOption)
|
2024-03-04 18:21:50 +08:00
|
|
|
case "dns":
|
|
|
|
dnsOptions := &outbound.DnsOption{}
|
|
|
|
err = decoder.Decode(mapping, dnsOptions)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
proxy = outbound.NewDnsWithOption(*dnsOptions)
|
2023-10-11 13:01:14 +08:00
|
|
|
case "reject":
|
|
|
|
rejectOption := &outbound.RejectOption{}
|
|
|
|
err = decoder.Decode(mapping, rejectOption)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
proxy = outbound.NewRejectWithOption(*rejectOption)
|
2024-03-08 17:38:27 +08:00
|
|
|
case "ssh":
|
|
|
|
sshOption := &outbound.SshOption{}
|
|
|
|
err = decoder.Decode(mapping, sshOption)
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
proxy, err = outbound.NewSsh(*sshOption)
|
2019-12-08 12:17:24 +08:00
|
|
|
default:
|
2020-08-25 22:19:59 +08:00
|
|
|
return nil, fmt.Errorf("unsupport proxy type: %s", proxyType)
|
2019-12-08 12:17:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-04-23 19:57:54 +08:00
|
|
|
if muxMapping, muxExist := mapping["smux"].(map[string]any); muxExist {
|
|
|
|
muxOption := &outbound.SingMuxOption{}
|
|
|
|
err = decoder.Decode(muxMapping, muxOption)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if muxOption.Enabled {
|
|
|
|
proxy, err = outbound.NewSingMux(*muxOption, proxy, proxy.(outbound.ProxyBase))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-08 12:17:24 +08:00
|
|
|
return NewProxy(proxy), nil
|
|
|
|
}
|